2009-04-27 1 views
26

Есть ли встроенный метод в .NET для преобразования числа в строковое представление числа? Например, один становится один, 2 становится два, и т.д..NET преобразовать число в строковое представление (от 1 до одного, от двух до двух и т. Д.)

+0

Я думаю, это язык и технологии (не только .NET) независимый вопрос. –

ответ

48

Я всегда был поклонником рекурсивного метода

public static string NumberToText(int n) 
    { 
    if (n < 0) 
     return "Minus " + NumberToText(-n); 
    else if (n == 0) 
     return ""; 
    else if (n <= 19) 
     return new string[] {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", 
     "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", 
     "Seventeen", "Eighteen", "Nineteen"}[n-1] + " "; 
    else if (n <= 99) 
     return new string[] {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", 
     "Eighty", "Ninety"}[n/10 - 2] + " " + NumberToText(n % 10); 
    else if (n <= 199) 
     return "One Hundred " + NumberToText(n % 100); 
    else if (n <= 999) 
     return NumberToText(n/100) + "Hundreds " + NumberToText(n % 100); 
    else if (n <= 1999) 
     return "One Thousand " + NumberToText(n % 1000); 
    else if (n <= 999999) 
     return NumberToText(n/1000) + "Thousands " + NumberToText(n % 1000); 
    else if (n <= 1999999) 
     return "One Million " + NumberToText(n % 1000000); 
    else if (n <= 999999999) 
     return NumberToText(n/1000000) + "Millions " + NumberToText(n % 1000000); 
    else if (n <= 1999999999) 
     return "One Billion " + NumberToText(n % 1000000000); 
    else 
     return NumberToText(n/1000000000) + "Billions " + NumberToText(n % 1000000000); 
} 

Source

+0

Хорошо, вы должны изменить его, по крайней мере, для получения долготы. +1 – BenAlabaster

+3

Мне понравился ваш код, поскольку его было легче следовать, чем балабастер. Я немного изменил его, чтобы учесть один параметр «0» (возвращает «Zero»), чтобы принять длинный, а не int, и вернуть Billion вместо Billions, Million вместо Millions и т. Д. Хороший код! –

+0

См. Мое сообщение для измененного кода. –

1

A conversion from integer to long form English... I could write that ;-) довольно хорошая статья на эту тему:

using System; 

public class NumberToEnglish { 
    private static string[] onesMapping = 
     new string[] { 
      "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", 
      "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" 
     }; 
    private static string[] tensMapping = 
     new string[] { 
      "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" 
     }; 
    private static string[] groupMapping = 
     new string[] { 
      "Hundred", "Thousand", "Million", "Billion", "Trillion" 
     }; 

    private static void Main(string[] args) { 
     Console.WriteLine(EnglishFromNumber(long.Parse(args[0]))); 
    } 

    private static string EnglishFromNumber(int number) { 
     return EnglishFromNumber((long) number); 
    } 

    private static string EnglishFromNumber(long number) { 
     if (number == 0) { 
      return onesMapping[number]; 
     } 

     string sign = "Positive"; 
     if (number < 0) { 
      sign = "Negative"; 
      number = Math.Abs(number); 
     } 

     string retVal = null; 
     int group = 0; 
     while(number > 0) { 
      int numberToProcess = (int) (number % 1000); 
      number = number/1000; 

      string groupDescription = ProcessGroup(numberToProcess); 
      if (groupDescription != null) { 
       if (group > 0) { 
        retVal = groupMapping[group] + " " + retVal; 
       } 
       retVal = groupDescription + " " + retVal; 
      } 

      group++; 
     } 

     return sign + " " + retVal; 
    } 

    private static string ProcessGroup(int number) { 
     int tens = number % 100; 
     int hundreds = number/100; 

     string retVal = null; 
     if (hundreds > 0) { 
      retVal = onesMapping[hundreds] + " " + groupMapping[0]; 
     } 
     if (tens > 0) { 
      if (tens < 20) { 
       retVal += ((retVal != null) ? " " : "") + onesMapping[tens]; 
      } else { 
       int ones = tens % 10; 
       tens = (tens/10) - 2; // 20's offset 

       retVal += ((retVal != null) ? " " : "") + tensMapping[tens]; 

       if (ones > 0) { 
        retVal += ((retVal != null) ? " " : "") + onesMapping[ones]; 
       } 
      } 
     } 

     return retVal; 
    } 
} 
+2

Очевидно, что это не кодовый гольф-соперник: P – BenAlabaster

+1

@balabaster: Также не так, как ваша версия для гольфа с кодом, но она * легко читается – BobTheBuilder

+0

@BobTheBuilder: Да, но, как я уже сказал, это не цель кода для гольфа: P – BenAlabaster

16

Ах, не может быть классом, чтобы сделать это, но был код гольф вопрос, который я предоставил # пример C для:

Code Golf: Number to Words

Однако, это не самый простой для чтения, и это идет только до decimal.MaxValue, поэтому я написал новый версия, которая пойдет так высоко, как вам нужно.

Я не мог найти информацию о значениях выше, чем vigintillions, но если вы добавите значения в массив you [], вы можете продолжить движение, насколько вам угодно. Он по-прежнему не поддерживает фракции, но я думаю о том, чтобы добавить это в какой-то момент.

static string NumericStringToWords(string NumericValue) 
    { 
     if ("0" == NumericValue) return "zero"; 

     string[] units = { "one", "two", "three", "four", "five", 
          "six", "seven", "eight", "nine" }; 

     string[] teens = { "eleven", "twelve", "thirteen", "four", "fifteen", 
          "sixteen", "seventeen", "eighteen", "nineteen" }; 

     string[] tens = { "ten", "twenty", "thirty", "forty", "fifty", 
          "sixty", "seventy", "eighty", "ninety" }; 

     string[] thou = { "thousand", "million", "billion", "trillion", 
          "quadrillion", "quintillion", "sextillion", 
          "septillion", "octillion", "nonillion", "decillion", 
          "udecillion", "duodecillion", "tredecillion", 
          "quattuordecillion", "quindecillion", "sexdecillion", 
          "septendecillion", "octodecillion", "novemdecillion", 
          "vigintillion" }; 

     string sign = String.Empty; 
     if ("-" == NumericValue.Substring(0, 1)) 
     { 
      sign = "minus "; 
      NumericValue = NumericValue.Substring(1); 
     } 

     int maxLen = thou.Length * 3; 
     int actLen = NumericValue.Length; 
     if(actLen > maxLen) 
      throw new InvalidCastException(String.Format("{0} digit number specified exceeds the maximum length of {1} digits. To evaluate this number, you must first expand the thou[] array.", actLen, maxLen)); 

     //Make sure that the value passed in is indeed numeric... we parse the entire string 
     //rather than just cast to a numeric type to allow us to handle large number types passed 
     //in as a string. Otherwise, we're limited to the standard data type sizes. 
     int n; //We don't care about n, but int.TryParse requires it 
     if (!NumericValue.All(c => int.TryParse(c.ToString(), out n))) 
      throw new InvalidCastException(); 

     string fraction = String.Empty; 
     if (NumericValue.Contains(".")) 
     { 
      string[] split = NumericValue.Split('.'); 
      NumericValue = split[0]; 
      fraction = split[1]; 
     } 

     StringBuilder word = new StringBuilder(); 
     ulong loopCount = 0; 

     while (0 < NumericValue.Length) 
     { 
      int startPos = Math.Max(0, NumericValue.Length - 3); 
      string crntBlock = NumericValue.Substring(startPos); 
      if (0 < crntBlock.Length) 
      { 
       //Grab the hundreds tens & units for the current block 
       int h = crntBlock.Length > 2 ? int.Parse(crntBlock[crntBlock.Length - 3].ToString()) : 0; 
       int t = crntBlock.Length > 1 ? int.Parse(crntBlock[crntBlock.Length - 2].ToString()) : 0; 
       int u = crntBlock.Length > 0 ? int.Parse(crntBlock[crntBlock.Length - 1].ToString()) : 0; 

       StringBuilder thisBlock = new StringBuilder(); 

       if (0 < u) 
        thisBlock.Append(1 == t? teens[u - 1] : units[u - 1]); 

       if (1 != t) 
       { 
        if (1 < t && 0 < u) thisBlock.Insert(0, "-"); 
        if (0 < t) thisBlock.Insert(0, tens[t - 1]); 
       } 

       if (0 < h) 
       { 
        if (t > 0 | u > 0) thisBlock.Insert(0, " and "); 
        thisBlock.Insert(0, String.Format("{0} hundred", units[h - 1])); 
       } 

       //Check to see if we've got any data left and add 
       //appropriate word separator ("and" or ",") 
       bool MoreLeft = 3 < NumericValue.Length; 
       if (MoreLeft && (0 == h) && (0 == loopCount)) 
        thisBlock.Insert(0, " and "); 
       else if (MoreLeft) 
        thisBlock.Insert(0, String.Format(" {0}, ", thou[loopCount])); 

       word.Insert(0, thisBlock); 
      } 

      //Remove the block we just evaluated from the 
      //input string for the next loop 
      NumericValue = NumericValue.Substring(0, startPos); 

      loopCount++; 
     } 
     return word.Insert(0, sign).ToString(); 
    } 

Я тестировал его с помощью Decimal.MaxValue добавляется к себе, чтобы генерировать большое количество:

семь octodecillion, девятьсот двадцать два septendecillion восемьсот шестнадцать sexdecillion, двести пятьдесят один квадциклин, четыреста двадцать шесть кватервондиллионов, четыреста тридцать три тридециллиона, семьсот пятьдесят девять дуодециллионов, триста пятьдесят четыре удециллиона, триста девяносто пять дециллионов, тридцать три миллиарда пятьсот и семьдесят девять octillion, двести двадцать восемь septillion, сто шестьдесят два sextillion, пятьсот четыре quintillion, двести шестьдесят четыре quadril лев, триста тридцать семь триллионов пятьсот девяносто три миллиарда пятьсот сорок три миллиона девятьсот пятьдесят тысяч триста тридцать пять

+2

+1 для продолжения до сих пор ... вы также должны добавить десятичные разряды ... – BobTheBuilder

+0

@BobTheBuilder: LOL, может быть, но я не уверен, как написать большую часть фракций. Вы пишете их как сотые, тысячные, или просто «нулевые пять пять девять ...» или вы пишете их как фактические фракции, такие как три пятых и т. Д.? – BenAlabaster

+0

Как насчет .1 = «одна десятая», .14 = «четырнадцать сотых», .141 = «сто сорок одна тысячная» и т. Д.? = P –

7

Вот измененный код я использовал:

//Wrapper class for NumberToText(int n) to account for single zero parameter. 
public static string ConvertToStringRepresentation(long number) 
{ 
    string result = null; 

    if (number == 0) 
    { 
     result = "Zero"; 
    } 
    else 
    { 
     result = NumberToText(number); 
    } 

    return result; 
} 

//Found at http://www.dotnet2themax.com/blogs/fbalena/PermaLink,guid,cdceca73-08cd-4c15-aef7-0f9c8096e20a.aspx. 
//Modifications from original source: 
// Changed parameter type from int to long. 
// Changed labels to be singulars instead of plurals (Billions to Billion, Millions to Million, etc.). 
private static string NumberToText(long n) 
{ 
    if (n < 0) 
     return "Minus " + NumberToText(-n); 
    else if (n == 0) 
     return ""; 
    else if (n <= 19) 
     return new string[] {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", 
           "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", 
           "Seventeen", "Eighteen", "Nineteen"}[n - 1] + " "; 
    else if (n <= 99) 
     return new string[] {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", 
           "Eighty", "Ninety"}[n/10 - 2] + " " + NumberToText(n % 10); 
    else if (n <= 199) 
     return "One Hundred " + NumberToText(n % 100); 
    else if (n <= 999) 
     return NumberToText(n/100) + "Hundred " + NumberToText(n % 100); 
    else if (n <= 1999) 
     return "One Thousand " + NumberToText(n % 1000); 
    else if (n <= 999999) 
     return NumberToText(n/1000) + "Thousand " + NumberToText(n % 1000); 
    else if (n <= 1999999) 
     return "One Million " + NumberToText(n % 1000000); 
    else if (n <= 999999999) 
     return NumberToText(n/1000000) + "Million " + NumberToText(n % 1000000); 
    else if (n <= 1999999999) 
     return "One Billion " + NumberToText(n % 1000000000); 
    else 
     return NumberToText(n/1000000000) + "Billion " + NumberToText(n % 1000000000); 
} 
7
public string IntToString(int number)//nobody really uses negative numbers 
{ 
    if(number == 0) 
     return "zero"; 
    else 
     if(number == 1) 
      return "one"; 
     ....... 
     else 
      if(number == 2147483647) 
       return "two billion one hundred forty seven million four hundred eighty three thousand six hundred forty seven"; 
} 
+4

Разве я не видел это на Daily WTF? –

+4

Нет, но это должно быть. Что я думал со всеми остальными, если. Я должен был использовать переключатель. – Kevin

+1

У меня возникает соблазн уменьшить это, но это так плохо, что оно действительно изменило мое решение .. +1 для чувства юмора. – nawfal

6

Эта тема была отличной помощью. Мне нравится решение Райана Эмерле, лучшее для его ясности. Вот моя версия, которая, я думаю, делает структуру понятной как день:

public static class Number 
{ 
    static string[] first = 
    { 
     "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", 
     "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", 
     "Seventeen", "Eighteen", "Nineteen" 
    }; 
    static string[] tens = 
    { 
     "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety", 
    }; 

    /// <summary> 
    /// Converts the given number to an english sentence. 
    /// </summary> 
    /// <param name="n">The number to convert.</param> 
    /// <returns>The string representation of the number.</returns> 
    public static string ToSentence(int n) 
    { 
     return n == 0 ? first[n] : Step(n); 
    } 
    // traverse the number recursively 
    public static string Step(int n) 
    { 
     return n < 0   ? "Minus " + Step(-n): 
       n == 0   ? "": 
       n <= 19   ? first[n]: 
       n <= 99   ? tens[n/10 - 2] + " " + Step(n % 10): 
       n <= 199   ? "One Hundred " + Step(n % 100): 
       n <= 999   ? Step(n/100) + "Hundred " + Step(n % 100): 
       n <= 1999  ? "One Thousand " + Step(n % 1000): 
       n <= 999999  ? Step(n/1000) + "Thousand " + Step(n % 1000): 
       n <= 1999999  ? "One Million " + Step(n % 1000000): 
       n <= 999999999 ? Step(n/1000000) + "Million " + Step(n % 1000000): 
       n <= 1999999999 ? "One Billion " + Step(n % 1000000000): 
            Step(n/1000000000) + "Billion " + Step(n % 1000000000); 
    } 
} 
+1

+1 для ясности и создания «констант» статического значения, в отличие от других решений, объявляющих их встроенными. – drzaus

1

Вот моя утонченная версия первого ответа. Надеюсь, это полезно.

/// <summary> 
/// Converts an <see cref="int"/> to its textual representation 
/// </summary> 
/// <param name="num"> 
/// The number to convert to text 
/// </param> 
/// <returns> 
/// A textual representation of the given number 
/// </returns> 
public static string ToText(this int num) 
{ 
    StringBuilder result; 

    if (num < 0) 
    { 
     return string.Format("Minus {0}", ToText(-num)); 
    } 

    if (num == 0) 
    { 
     return "Zero"; 
    } 

    if (num <= 19) 
    { 
     var oneToNineteen = new[] 
     { 
      "One", 
      "Two", 
      "Three", 
      "Four", 
      "Five", 
      "Six", 
      "Seven", 
      "Eight", 
      "Nine", 
      "Ten", 
      "Eleven", 
      "Twelve", 
      "Thirteen", 
      "Fourteen", 
      "Fifteen", 
      "Sixteen", 
      "Seventeen", 
      "Eighteen", 
      "Nineteen" 
     }; 

     return oneToNineteen[num - 1]; 
    } 

    if (num <= 99) 
    { 
     result = new StringBuilder(); 

     var multiplesOfTen = new[] 
     { 
      "Twenty", 
      "Thirty", 
      "Forty", 
      "Fifty", 
      "Sixty", 
      "Seventy", 
      "Eighty", 
      "Ninety" 
     }; 

     result.Append(multiplesOfTen[(num/10) - 2]); 

     if (num % 10 != 0) 
     { 
      result.Append(" "); 
      result.Append(ToText(num % 10)); 
     } 

     return result.ToString(); 
    } 

    if (num == 100) 
    { 
     return "One Hundred"; 
    } 

    if (num <= 199) 
    { 
     return string.Format("One Hundred and {0}", ToText(num % 100)); 
    } 

    if (num <= 999) 
    { 
     result = new StringBuilder((num/100).ToText()); 
     result.Append(" Hundred"); 
     if (num % 100 != 0) 
     { 
      result.Append(" and "); 
      result.Append((num % 100).ToText()); 
     } 

     return result.ToString(); 
    } 

    if (num <= 999999) 
    { 
     result = new StringBuilder((num/1000).ToText()); 
     result.Append(" Thousand"); 
     if (num % 1000 != 0) 
     { 
      switch ((num % 1000) < 100) 
      { 
       case true: 
        result.Append(" and "); 
        break; 
       case false: 
        result.Append(", "); 
        break; 
      } 

      result.Append((num % 1000).ToText()); 
     } 

     return result.ToString(); 
    } 

    if (num <= 999999999) 
    { 
     result = new StringBuilder((num/1000000).ToText()); 
     result.Append(" Million"); 
     if (num % 1000000 != 0) 
     { 
      switch ((num % 1000000) < 100) 
      { 
       case true: 
        result.Append(" and "); 
        break; 
       case false: 
        result.Append(", "); 
        break; 
      } 

      result.Append((num % 1000000).ToText()); 
     } 

     return result.ToString(); 
    } 

    result = new StringBuilder((num/1000000000).ToText()); 
    result.Append(" Billion"); 
    if (num % 1000000000 != 0) 
    { 
     switch ((num % 1000000000) < 100) 
     { 
      case true: 
       result.Append(" and "); 
       break; 
      case false: 
       result.Append(", "); 
       break; 
     } 

     result.Append((num % 1000000000).ToText()); 
    } 

    return result.ToString(); 
} 
3

на основе решения Райана Emerle, это добавляет тире в правильных местах, не включает в себя завершающие пробелы, не множественном числе чисел, и правильно обрабатывает ввод нуля (0):

public static string ToText(long n) { 
    return _toText(n, true); 
} 
private static string _toText(long n, bool isFirst = false) { 
    string result; 
    if(isFirst && n == 0) { 
     result = "Zero"; 
    } else if(n < 0) { 
     result = "Negative " + _toText(-n); 
    } else if(n == 0) { 
     result = ""; 
    } else if(n <= 9) { 
     result = new[] { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" }[n - 1] + " "; 
    } else if(n <= 19) { 
     result = new[] { "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }[n - 10] + (isFirst ? null : " "); 
    } else if(n <= 99) { 
     result = new[] { "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }[n/10 - 2] + (n % 10 > 0 ? "-" + _toText(n % 10) : null); 
    } else if(n <= 999) { 
     result = _toText(n/100) + "Hundred " + _toText(n % 100); 
    } else if(n <= 999999) { 
     result = _toText(n/1000) + "Thousand " + _toText(n % 1000); 
    } else if(n <= 999999999) { 
     result = _toText(n/1000000) + "Million " + _toText(n % 1000000); 
    } else { 
     result = _toText(n/1000000000) + "Billion " + _toText(n % 1000000000); 
    } 
    if(isFirst) { 
     result = result.Trim(); 
    } 
    return result; 
} 
1

В .net нет встроенного решения, но вокруг есть хорошие библиотеки.Лучшее в настоящее время, безусловно, Humanizr:

Console.WriteLine(794663.ToWords()); // => seven hundred and ninety-four thousand six hundred and sixty-three 

Он также поддерживает порядковое, и римские представления:

Console.WriteLine(794663.ToOrdinalWords()); // => seven hundred and ninety-four thousand six hundred and sixty third 
Console.WriteLine(794.ToRoman()); // => DCCXCIV 

Humanizr также имеет широкий спектр инструментов, в отношении string, DateTime, TimeSpan и т.д. ,

Console.WriteLine(794.Seconds().Humanize().Underscore().Hyphenate()); // => 13-minutes 
0

Другое naasking, версия в VB.NET, если кому-то интересно! Пришлось использовать функцию пола для правильного округления.

Public Function NumberToText(n As Integer) As String 
     Dim a As String() = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"} 
     Dim tens As String() = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", 
     "Eighty", "Ninety"} 

     If (n < 0) Then 
      Return "Minus " + NumberToText(-n) 
     ElseIf (n = 0) Then 
      Return "" 
     ElseIf (n <= 19) Then 
      Return a(n - 1) + " " 
     ElseIf (n <= 99) Then 
      Return tens(Math.Floor(n/10) - 2) + " " + NumberToText(n Mod 10) 
     ElseIf (n <= 199) Then 
      Return "One Hundred " + NumberToText(n Mod 100) 
     ElseIf (n <= 999) Then 
      Return NumberToText(Math.Floor(n/100)) + "Hundreds " + NumberToText(n Mod 100) 
     ElseIf (n <= 1999) Then 
      Return "One Thousand " + NumberToText(n Mod 1000) 
     ElseIf (n <= 999999) Then 
      Return NumberToText(Math.Floor(n/1000)) + "Thousands " + NumberToText(n Mod 1000) 
     ElseIf (n <= 1999999) Then 
      Return "One Million " + NumberToText(n Mod 1000000) 
     ElseIf (n <= 999999999) Then 
      Return NumberToText(Math.Floor(n/1000000)) + "Millions " + NumberToText(n Mod 1000000) 
     ElseIf (n <= 1999999999) Then 
      Return "One Billion " + NumberToText(n Mod 1000000000) 
     Else 
      Return NumberToText(Math.Floor(n/1000000000)) + "Billions " + NumberToText(n Mod 1000000000) 
     End If 

    End Function 
0

Это более полное/улучшенное решение, основанное на парах идей, также размещенных здесь. Включает в себя грамматику/дефис исправления, а также дополнительную капитализацию, поддержка длинных, поддержка нуля, и все еще очень сжатое (VB.NET):

Function NumberToCapitalizedWords(ByVal n As Long) As String 
    Return New System.Globalization.CultureInfo("en-US", False).TextInfo.ToTitleCase(NumberToWords(n)) 
End Function 

Function NumberToWords(ByVal n As Long) As String 
    Return LTrim(NumberToWords(n, False, False)) 
End Function 

Function NumberToWords(ByVal n As Long, ByVal recursed As Boolean, ByVal iesLast As Boolean) As String 
    If (n < 0) Then 
     Return "negative" + NumberToWords(-n, False, False) 
    ElseIf (n = 0) Then 
     If recursed Then 
      Return "" 
     End If 
     Return "zero" 
    ElseIf (n < 20) Then 
     Return If(iesLast, "-", " ") + New String() {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}(n - 1) 
    ElseIf (n < 100) Then 
     Return " " + New String() {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"}(n \ 10 - 2) + NumberToWords(n Mod 10, True, True) 
    ElseIf (n < 1000) Then 

     Return NumberToWords(n \ 100, True, False) + " hundred" + NumberToWords(n Mod 100, True, False) 
    Else 
     Dim log1000 As Integer = Math.Floor(Math.Log(n, 1000)) 
     Return NumberToWords(n \ PowerNoFloat(1000, log1000), True, False) + " " + New String() {"thousand", "million", "billion", "trillion", "quadrillion", "quintillion"}(log1000 - 1) + NumberToWords(n Mod PowerNoFloat(1000, log1000), True, False) 
    End If 

End Function 

Function PowerNoFloat(ByRef base As Long, ByRef power As Integer) As Long 
    If power < 0 Then 
     Return 0 
    End If 
    Dim result As Long = 1 
    For i As Integer = 1 To power 
     result *= base 
    Next 
    Return result 
End Function 
+0

Я добавил функцию дополнительной мощности, потому что встроенная функция языка возвращает двойной, который может вызвать расхождения. –

Смежные вопросы