How can I convert an integer into its verbal representation?

后端 未结 14 2159
走了就别回头了
走了就别回头了 2020-11-22 15:23

Is there a library or a class/function that I can use to convert an integer to it\'s verbal representation?

Example input:

4,567,788`

相关标签:
14条回答
  • 2020-11-22 15:54

    Here is the spanish version:

            public static string numeroALetras(int number)
        {
            if (number == 0)
                return "cero";
    
            if (number < 0)
                return "menos " + numeroALetras(Math.Abs(number));
    
            string words = "";
    
            if ((number / 1000000) > 0)
            {
                words += numeroALetras(number / 1000000) + " millón ";
                number %= 1000000;
            }
    
            if ((number / 1000) > 0)
            {
                words += (number / 1000) == 1? "mil ": numeroALetras(number / 1000) + " mil ";
                number %= 1000;
            }
            if ((number / 100) == 1)
            {
                if (number == 100)
                    words += "cien";
                else words += (number / 100)> 1? numeroALetras(number / 100) + " ciento ":"ciento ";
                number %= 100;
            }
            if ((number / 100) > 1)
            {
                var hundredMap = new[] {"","", "dosc", "tresc", "cuatroc", "quin", "seisc", "sietec", "ochoc", "novec" };
                if (number > 199)
                    words += hundredMap[number/100] + "ientos ";
                else {
                    words += numeroALetras(number / 100) + " ientos ";
                }
                number %= 100;
            }
    
            if (number > 0)
            {
                if (words != "")
                    words += " ";
    
                var unitsMap = new[] { "cero", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve", "diez", "once", "doce", "trece", "catorce", "quince", "dieciseis", "diecisiete", "dieciocho", "diecinueve", "veinte" };
                var tensMap = new[] { "cero", "diez", "veinti", "treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta", "noventa" };
    
                if (number < 21)
                    words += unitsMap[number];
                else
                {                    
                    words += tensMap[number / 10];
                    if ((number % 10) > 0)
                        words += ((number % 10)>2?" y ": "") + unitsMap[number % 10];                    
                }
            }
    
            return words;
        }
    
    0 讨论(0)
  • 2020-11-22 15:56

    This class perfectly converts your float or double (till 2 precision). Just copy and paste in your IDE and see the result.

    class ConversionClass
    {
        private static Dictionary<int, string> InitialNumbers = new Dictionary<int, string>();
        private static Dictionary<int, string> MultipleOfTen = new Dictionary<int, string>();
        private static Dictionary<int, string> MultipleOfHundered = new Dictionary<int, string>();
    
        private static void InitializeStatic()
        {
            //InitialNumbers.Add(0, "zero");
            InitialNumbers.Add(1, "one");
            InitialNumbers.Add(2, "two");
            InitialNumbers.Add(3, "three");
            InitialNumbers.Add(4, "four");
            InitialNumbers.Add(5, "five");
            InitialNumbers.Add(6, "six");
            InitialNumbers.Add(7, "seven");
            InitialNumbers.Add(8, "eight");
            InitialNumbers.Add(9, "nine");
            InitialNumbers.Add(10, "ten");
            InitialNumbers.Add(11, "eleven");
            InitialNumbers.Add(12, "tweleve");
            InitialNumbers.Add(13, "thirteen");
            InitialNumbers.Add(14, "fourteen");
            InitialNumbers.Add(15, "fifteen");
            InitialNumbers.Add(16, "sixteen");
            InitialNumbers.Add(17, "seventeen");
            InitialNumbers.Add(18, "eighteen");
            InitialNumbers.Add(19, "nineteen");
    
            MultipleOfTen.Add(1, "ten");
            MultipleOfTen.Add(2, "twenty");
            MultipleOfTen.Add(3, "thirty");
            MultipleOfTen.Add(4, "fourty");
            MultipleOfTen.Add(5, "fifty");
            MultipleOfTen.Add(6, "sixty");
            MultipleOfTen.Add(7, "seventy");
            MultipleOfTen.Add(8, "eighty");
            MultipleOfTen.Add(9, "ninety");
    
            MultipleOfHundered.Add(2, "hundred");                      //                100
            MultipleOfHundered.Add(3, "thousand");                     //              1 000
            MultipleOfHundered.Add(4, "thousand");                     //             10 000
            MultipleOfHundered.Add(5, "thousand");                     //            100 000
            MultipleOfHundered.Add(6, "million");                      //          1 000 000
            MultipleOfHundered.Add(7, "million");                      //        100 000 000
            MultipleOfHundered.Add(8, "million");                      //      1 000 000 000
            MultipleOfHundered.Add(9, "billion");                      //  1 000 000 000 000
        }
    
        public static void Main()
        {
            InitializeStatic();
            Console.WriteLine("Enter number :");
            var userInput = Console.ReadLine();
            double userValue ;
            if (double.TryParse(userInput, out userValue))  // userValue = 193524019.50
            {
                int decimalPortion = (int)userValue;
                //var fractionPortion = Math.Ceiling(((userValue < 1.0) ? userValue : (userValue % Math.Floor(userValue))) * 100);
                int fractionPortion = (int)(userValue * 100) - ((int)userValue * 100);
    
                int digit; int power;
                StringBuilder numberInText = new StringBuilder();
    
                while (decimalPortion > 0)
                {
                    GetDigitAndPower(decimalPortion, out digit, out power);
                    numberInText.Append(ConvertToText(ref decimalPortion, ref digit, ref power));
                    if (decimalPortion > 0)
                    {
                        decimalPortion = GetReminder(decimalPortion, digit, power);
                    }
                }
                numberInText.Append(" point ");
                while (fractionPortion > 0)
                {
                    GetDigitAndPower(fractionPortion, out digit, out power);
                    numberInText.Append(ConvertToText(ref fractionPortion, ref digit, ref power));
                    if (fractionPortion > 0)
                    {
                        fractionPortion = GetReminder(fractionPortion, digit, power);
                    }
                }
    
                Console.WriteLine(numberInText.ToString());
            }
            Console.ReadKey();
        }
    
        private static int GetReminder(int orgValue, int digit, int power)
        {
            int returningValue = orgValue - (digit * (int)Math.Pow(10, power));
            return returningValue;
        }
    
        private static void GetDigitAndPower(int originalValue, out int digit, out int power)
        {
            for (power = 0, digit = 0; power < 10; power++)
            {
                var divisionFactor = (int)Math.Pow(10, power);
                int operationalValue = (originalValue / divisionFactor);
                if (operationalValue <= 0)
                {
                    power = power - 1;
                    digit = (int)(originalValue / Math.Pow(10, power));
                    break;
                }
            } 
        }
    
        private static string ConvertToText(ref int orgValue, ref int digit, ref int power)
        {
            string numberToText = string.Empty;
    
            if (power < 2)
            {
                if (InitialNumbers.ContainsKey(orgValue))
                {
                    //This is for number 1 to 19
                    numberToText = InitialNumbers[orgValue];
                    orgValue = 0;
                }
                else if (MultipleOfTen.ContainsKey(digit))
                {
                    //This is for multiple of 10 (20,30,..90)
                    numberToText = MultipleOfTen[digit];
                }
            }
            else
            {
                if (power < 4)
                {
                    numberToText = string.Format("{0} {1}", InitialNumbers[digit], MultipleOfHundered[power]);
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    int multiplicationFactor = power / 3;
                    int innerOrgValue = (int) (orgValue / Math.Pow(10, (multiplicationFactor * 3)));
                    digit = innerOrgValue;
                    var multiple = MultipleOfHundered[power];
                    power = power - ((int)Math.Ceiling(Math.Log10(innerOrgValue)) - 1);
    
                    int innerPower = 0;
                    int innerDigit = 0;
                    while (innerOrgValue > 0)
                    {
                        GetDigitAndPower(innerOrgValue, out innerDigit, out innerPower);
                        var text = ConvertToText(ref innerOrgValue, ref innerDigit, ref innerPower);
                        sb.Append(text);
                        sb.Append(" ");
                        if (innerOrgValue > 0)
                        {
                            innerOrgValue = GetReminder(innerOrgValue, innerDigit, innerPower);
                        }
                    }
                    sb.Append(multiple);
                    numberToText = sb.ToString();
    
                }
            }
    
            return numberToText + " ";
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 15:57

    http://www.exchangecore.com/blog/convert-number-words-c-sharp-console-application/ has some C# script that looks to handle very large numbers and very small decimals.

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace NumWords
    {
        class Program
        {
            // PROGRAM HANDLES NEGATIVE AND POSITIVE DOUBLES
    
    
            static String NumWordsWrapper(double n)
            {
                string words = "";
                double intPart;
                double decPart = 0;
                if (n == 0)
                    return "zero";
                try {
                    string[] splitter = n.ToString().Split('.');
                    intPart = double.Parse(splitter[0]);
                    decPart = double.Parse(splitter[1]);
                } catch {
                    intPart = n;
                }
    
                words = NumWords(intPart);
    
                if (decPart > 0) {
                    if (words != "")
                        words += " and ";
                    int counter = decPart.ToString().Length;
                    switch (counter) {
                        case 1: words += NumWords(decPart) + " tenths"; break;
                        case 2: words += NumWords(decPart) + " hundredths"; break;
                        case 3: words += NumWords(decPart) + " thousandths"; break;
                        case 4: words += NumWords(decPart) + " ten-thousandths"; break;
                        case 5: words += NumWords(decPart) + " hundred-thousandths"; break;
                        case 6: words += NumWords(decPart) + " millionths"; break;
                        case 7: words += NumWords(decPart) + " ten-millionths"; break;
                    }
                }
                return words;
            }
    
            static String NumWords(double n) //converts double to words
            {
                string[] numbersArr = new string[] { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
                string[] tensArr = new string[] { "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninty" };
                string[] suffixesArr = new string[] { "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion", "undecillion", "duodecillion", "tredecillion", "Quattuordecillion", "Quindecillion", "Sexdecillion", "Septdecillion", "Octodecillion", "Novemdecillion", "Vigintillion" };
                string words = "";
    
                bool tens = false;
    
                if (n < 0) {
                    words += "negative ";
                    n *= -1;
                }
    
                int power = (suffixesArr.Length + 1) * 3;
    
                while (power > 3) {
                    double pow = Math.Pow(10, power);
                    if (n >= pow) {
                        if (n % pow > 0) {
                            words += NumWords(Math.Floor(n / pow)) + " " + suffixesArr[(power / 3) - 1] + ", ";
                        } else if (n % pow == 0) {
                            words += NumWords(Math.Floor(n / pow)) + " " + suffixesArr[(power / 3) - 1];
                        }
                        n %= pow;
                    }
                    power -= 3;
                }
                if (n >= 1000) {
                    if (n % 1000 > 0) words += NumWords(Math.Floor(n / 1000)) + " thousand, ";
                    else words += NumWords(Math.Floor(n / 1000)) + " thousand";
                    n %= 1000;
                }
                if (0 <= n && n <= 999) {
                    if ((int)n / 100 > 0) {
                        words += NumWords(Math.Floor(n / 100)) + " hundred";
                        n %= 100;
                    }
                    if ((int)n / 10 > 1) {
                        if (words != "")
                            words += " ";
                        words += tensArr[(int)n / 10 - 2];
                        tens = true;
                        n %= 10;
                    }
    
                    if (n < 20 && n > 0) {
                        if (words != "" && tens == false)
                            words += " ";
                        words += (tens ? "-" + numbersArr[(int)n - 1] : numbersArr[(int)n - 1]);
                        n -= Math.Floor(n);
                    }
                }
    
                return words;
    
            }
            static void Main(string[] args)
            {
                Console.Write("Enter a number to convert to words: ");
                Double n = Double.Parse(Console.ReadLine());
    
                Console.WriteLine("{0}", NumWordsWrapper(n));
            }
        }
    }
    

    EDIT: brought code over from blog post

    0 讨论(0)
  • 2020-11-22 15:58

    I actually needed this for an app I'm working on, but wasn't happy with any of the solutions here. FYI, this solution takes advantage of C# 7.0's support for local functions. I also used the new digit separator to make the larger numbers more readable.

    public static class NumberExtensions
    {
        private const string negativeWord = "negative";
        private static readonly Dictionary<ulong, string> _wordMap = new Dictionary<ulong, string>
        {
            [1_000_000_000_000_000_000] = "quintillion",
            [1_000_000_000_000_000] = "quadrillion",
            [1_000_000_000_000] = "trillion",
            [1_000_000_000] = "billion",
            [1_000_000] = "million",
            [1_000] = "thousand",
            [100] = "hundred",
            [90] = "ninety",
            [80] = "eighty",
            [70] = "seventy",
            [60] = "sixty",
            [50] = "fifty",
            [40] = "forty",
            [30] = "thirty",
            [20] = "twenty",
            [19] = "nineteen",
            [18] = "eighteen",
            [17] = "seventeen",
            [16] = "sixteen",
            [15] = "fifteen",
            [14] = "fourteen",
            [13] = "thirteen",
            [12] = "twelve",
            [11] = "eleven",
            [10] = "ten",
            [9] = "nine",
            [8] = "eight",
            [7] = "seven",
            [6] = "six",
            [5] = "five",
            [4] = "four",
            [3] = "three",
            [2] = "two",
            [1] = "one",
            [0] = "zero"
        };
    
        public static string ToWords(this short num)
        {
            var words = ToWords((ulong)Math.Abs(num));
            return num < 0 ? $"{negativeWord} {words}" : words;
        }
    
        public static string ToWords(this ushort num)
        {
            return ToWords((ulong)num);
        }
    
        public static string ToWords(this int num)
        {
            var words = ToWords((ulong)Math.Abs(num));
            return num < 0 ? $"{negativeWord} {words}" : words;
        }
    
        public static string ToWords(this uint num)
        {
            return ToWords((ulong)num);
        }
    
        public static string ToWords(this long num)
        {
            var words = ToWords((ulong)Math.Abs(num));
            return num < 0 ? $"{negativeWord} {words}" : words;
        }
    
        public static string ToWords(this ulong num)
        {
            var sb = new StringBuilder();
            var delimiter = String.Empty;
    
            void AppendWords(ulong dividend)
            {
                void AppendDelimitedWord(ulong key)
                {
                    sb.Append(delimiter);
                    sb.Append(_wordMap[key]);
                    delimiter = 20 <= key && key < 100 ? "-" : " ";
                }
    
                if (_wordMap.ContainsKey(dividend))
                {
                    AppendDelimitedWord(dividend);
                }
                else
                {
                    var divisor = _wordMap.First(m => m.Key <= dividend).Key;
                    var quotient = dividend / divisor;
                    var remainder = dividend % divisor;
    
                    if (quotient > 0 && divisor >= 100)
                    {
                        AppendWords(quotient);
                    }
    
                    AppendDelimitedWord(divisor);
    
                    if (remainder > 0)
                    {   
                        AppendWords(remainder);
                    }
                }
            }
    
            AppendWords(num);
            return sb.ToString();
        }    
    }
    

    The meat is in the last ToWords overload.

    0 讨论(0)
  • 2020-11-22 16:01

    Though this is kind of old question, I have implemented this functionality with more detailed approach

    public static class NumberToWord
        {
            private static readonly Dictionary<long, string> MyDictionary = new Dictionary<long, string>();
    
            static NumberToWord()
            {
                MyDictionary.Add(1000000000000000, "quadrillion");
                MyDictionary.Add(1000000000000, "trillion");
                MyDictionary.Add(1000000000, "billion");
                MyDictionary.Add(1000000, "million");
                MyDictionary.Add(1000, "thousand");
                MyDictionary.Add(100, "hundread");
                MyDictionary.Add(90, "ninety");
                MyDictionary.Add(80, "eighty");
                MyDictionary.Add(70, "seventy");
                MyDictionary.Add(60, "sixty");
                MyDictionary.Add(50, "fifty");
                MyDictionary.Add(40, "fourty");
                MyDictionary.Add(30, "thirty");
                MyDictionary.Add(20, "twenty");
                MyDictionary.Add(19, "nineteen");
                MyDictionary.Add(18, "eighteen");
                MyDictionary.Add(17, "seventeen");
                MyDictionary.Add(16, "sixteen");
                MyDictionary.Add(15, "fifteen");
                MyDictionary.Add(14, "fourteen");
                MyDictionary.Add(13, "thirteen");
                MyDictionary.Add(12, "twelve");
                MyDictionary.Add(11, "eleven");
                MyDictionary.Add(10, "ten");
                MyDictionary.Add(9, "nine");
                MyDictionary.Add(8, "eight");
                MyDictionary.Add(7, "seven");
                MyDictionary.Add(6, "six");
                MyDictionary.Add(5, "five");
                MyDictionary.Add(4, "four");
                MyDictionary.Add(3, "three");
                MyDictionary.Add(2, "two");
                MyDictionary.Add(1, "one");
                MyDictionary.Add(0, "zero");
            }
    
            /// <summary>
            /// To the verbal.
            /// </summary>
            /// <param name="value">The value.</param>
            /// <returns></returns>
            public static string ToVerbal(this int value)
            {
                return ToVerbal((long) value);
            }
    
            /// <summary>
            /// To the verbal.
            /// </summary>
            /// <param name="value">The value.</param>
            /// <returns></returns>
            public static string ToVerbal(this long value)
            {
                if (value == 0) return MyDictionary[value];
    
                if (value < 0)
                    return $" negative {ToVerbal(Math.Abs(value))}";
    
                var builder = new StringBuilder();
    
                for (var i = 1000000000000000; i >= 1000; i = i/1000)
                    value = ConstructWord(value, builder, i);
    
                value = ConstructWord(value, builder, 100);
    
                for (var i = 90; i >= 20; i = i - 10)
                    value = ConstructWordForTwoDigit(value, builder, i);
    
                if (MyDictionary.ContainsKey(value))
                    builder.AppendFormat("{0}" + MyDictionary[value], builder.Length > 0 
                        ? " " 
                        : string.Empty);
    
                return builder.ToString();
            }
    
            private static long ConstructWord(long value, StringBuilder builder, long key)
            {
                if (value >= key)
                {
                    var unit = (int) (value/key);
                    value -= unit*key;
                    builder.AppendFormat(" {0} {1} " + MyDictionary[key], builder.Length > 0
                        ? ", "
                        : string.Empty, ToVerbal(unit));
                }
                return value;
            }
            private static long ConstructWordForTwoDigit(long value, StringBuilder builder, long key)
            {
                if (value >= key)
                {
                    value -= key;
                    builder.AppendFormat(" {0} " + MyDictionary[key], builder.Length > 0
                        ? " "
                        : string.Empty);
                }
                return value;
            } 
        }
    

    FYI: i have user string interpolation which is only available in 4.6.1

    0 讨论(0)
  • 2020-11-22 16:02

    I was tasked to create a WEB API that converts numbers to words using C#.

    Can be whole number or with decimal points in 48 hours time.

    The call will be coming from a front-end application using Ajax Post method and return the converted result in the webpage.

    I've publicly shared that project in the GitHub for reference: https://github.com/marvinglennlacuna/NumbersToWordsConverter.Api

    With the following technical implementatation in placed:

    1. MVC structured
    2. API Controller
    3. Service
    4. Model
    5. Error Handling
    6. Unit Testing using MSTest
    7. Code Coverage - 98%
    8. Jquery

    And with technical documentation about the following as well:

    1. Purpose
    2. Prerequisites
    3. Functionl Requirements
    4. Process Diagram and Output

    **Result via Web Page (US-001) **

    US-001 Convert Numbers to Words via web page process

    US-001 Convert Numbers to Words via web page output

    Result via Postman (US-002)

    US-002 - Convert Numbers to Words via Postman process

    US-002 - Convert Numbers to Words via Postman output

    I think it's just worth sharing a working solution in the case you need it for reference in interview/code test/school or for fun only.

    Cheers, Marvin

    0 讨论(0)
提交回复
热议问题