How can I convert an integer into its verbal representation?

后端 未结 14 2326
走了就别回头了
走了就别回头了 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: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 _wordMap = new Dictionary
        {
            [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.

提交回复
热议问题