2009-02-16 19 views

Respuesta

25

si utiliza el código encontrado en: converting numbers in to words C# y que lo necesite para números decimales, aquí está cómo hacerlo:

public string DecimalToWords(decimal number) 
{ 
    if (number == 0) 
     return "zero"; 

    if (number < 0) 
     return "minus " + DecimalToWords(Math.Abs(number)); 

    string words = ""; 

    int intPortion = (int)number; 
    decimal fraction = (number - intPortion)*100; 
    int decPortion = (int)fraction; 

    words = NumericToWords(intPortion); 
    if (decPortion > 0) 
    { 
     words += " and "; 
     words += NumericToWords(decPortion); 
    } 
    return words; 
} 
+0

Cuando estoy usando decimal en la cantidad, no quiero "Y" que se produzca dos veces, una con "Número de Palabras" uno con "Decimal", que sólo debe ocurrir cuando no hay decimal, si hay un decimal, debe ocurrir solo con decimal. – Patrick

1

http://www.exchangecore.com/blog/convert-number-words-c-sharp-console-application/ tiene alguna secuencia de comandos C# que se parece a manejar números muy grandes y muy pequeñas decimales.

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: trajo código a través de la entrada de blog

2
Imports System.Text 

Public Class NumberWriter 

    Public Shared Function Parse(ByVal Number As String) As String 
     If Not AreNumbers(Number) Then Return "" 
     Dim TempQueue As New Queue(Of String) 
     For Each ItemA As Char In Number.Replace(",", "").Reverse 
      TempQueue.Enqueue(ItemA) 
     Next 
     Dim Blocks As New List(Of String) 
     Dim BlockEmpty As New List(Of Boolean) 
     Do 
      Dim TempBlock As New StringBuilder(3) 
      TempBlock.Append(TempQueue.Dequeue) 
      If TempQueue.Count > 0 Then 
       TempBlock.Append(TempQueue.Dequeue) 
       If TempQueue.Count > 0 Then 
        TempBlock.Append(TempQueue.Dequeue) 
       End If 
      End If 
      Blocks.Add(StrReverse(TempBlock.ToString)) 
      BlockEmpty.Add(TempBlock.ToString = "000") 
      If TempQueue.Count < 1 Then Exit Do 
     Loop 
     Dim ResultStack As New Stack(Of String) 
     For int1 As Integer = 0 To Blocks.Count - 1 
      ResultStack.Push(ReadBlock(Blocks(int1)) & If(Not int1 = 0, If(Not BlockEmpty(int1), " " & CapitalizeWord(GetPlaceValueSet(int1)) & If(BlockEmpty(int1 - 1), "", ", "), ""), "")) 
     Next 
     Dim Result1 As String = "" 
     Do Until ResultStack.Count < 1 
      Result1 &= ResultStack.Pop 
     Loop 
     Return RemoveGrammarErrors(Result1) 
    End Function 

    Private Shared Function RemoveGrammarErrors(ByVal Str As String) As String 
     Dim tstr As String = Str 
     tstr.Replace(" ", " ") 
     tstr.Replace(" , ", ", ") 
     Return tstr 
    End Function 

    Private Shared Function AreNumbers(ByVal Str1 As String) As Boolean 
     Dim Numbers() As String = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ","} 
     For Each ItemA As Char In Str1 
      Dim IsN As Boolean = False 
      For Each ItemB As String In Numbers 
       If ItemA = ItemB Then IsN = True 
      Next 
      If Not IsN Then 
       Return False 
      End If 
     Next 
     Return True 
    End Function 

    Private Shared Function ReadBlock(ByVal Block As String) 
     Select Case Block.Length 
      Case 1 
       Return ReadSingleDigit(Block) 
      Case 2 
       Return ReadTwoDigits(Block) 
      Case 3 
       Return ReadThreeDigits(Block) 
      Case Else 
       Throw New Exception 
     End Select 
    End Function 

    Private Shared Function ReadThreeDigits(ByVal Digits As String) 
     If Digits.Length > 3 Then Throw New ArgumentException("There are too many digits.") 
     Dim Result As String = "" 
     If Not Digits(0) = "0" Then 
      Result &= ReadSingleDigit(Digits(0)) & " Hundred " 
     End If 
     Result &= ReadTwoDigits(Digits.Substring(1)) 
     Return Result 
    End Function 

    Private Shared Function ReadTwoDigits(ByVal Digits As String) 
     If Digits.Length > 2 Then Throw New ArgumentException("There are too many digits.") 
     Select Case Digits(0) 
      Case "0" 
       Return ReadSingleDigit(Digits(1)) 
      Case "1" 
       Return ReadTeenNumber(Digits) 
      Case Else 
       Return ReadFirstInNumberPair(Digits(0)) & If(Digits(1) = "0", "", "-" & ReadSingleDigit(Digits(1))) 
     End Select 
    End Function 

    Private Shared Function ReadSingleDigit(ByVal Digit As String) As String 
     If Not Digit.Length = 1 Then Throw New ArgumentException("There must be only one digit and it must be more than zero.") 
     Select Case Digit 
      Case "0" 
       Return "" 
      Case "1" 
       Return "One" 
      Case "2" 
       Return "Two" 
      Case "3" 
       Return "Three" 
      Case "4" 
       Return "Four" 
      Case "5" 
       Return "Five" 
      Case "6" 
       Return "Six" 
      Case "7" 
       Return "Seven" 
      Case "8" 
       Return "Eight" 
      Case "9" 
       Return "Nine" 
      Case Else 
       Throw New Exception() 
     End Select 
    End Function 

    Private Shared Function ReadTeenNumber(ByVal Num As String) As String 
     Select Case Num 
      Case "11" 
       Return "Eleven" 
      Case "12" 
       Return "Twelve" 
      Case "13" 
       Return "Thirteen" 
      Case "14" 
       Return "Fourteen" 
      Case "15" 
       Return "Fifteen" 
      Case "16" 
       Return "Sixteen" 
      Case "17" 
       Return "Seventeen" 
      Case "18" 
       Return "Eighteen" 
      Case "19" 
       Return "Nineteen" 
      Case Else 
       Throw New Exception() 
     End Select 
    End Function 

    Private Shared Function ReadFirstInNumberPair(ByVal Num As String) As String 
     If Not (Num > 1 OrElse Num < 10) Then Throw New ArgumentException("Number must be more than 1 and less than 10") 
     Select Case Num 
      Case "2" 
       Return "Twenty" 
      Case "3" 
       Return "Thirty" 
      Case "4" 
       Return "Fourty" 
      Case "5" 
       Return "Fifty" 
      Case "6" 
       Return "Sixty" 
      Case "7" 
       Return "Seventy" 
      Case "8" 
       Return "Eighty" 
      Case "9" 
       Return "Ninety" 
      Case Else 
       Throw New Exception() 
     End Select 
    End Function 

    Private Shared Function CapitalizeWord(ByVal Word As String) As String 
     Return Word.Substring(0, 1).ToUpper & Word.Substring(1) 
    End Function 

    Private Shared Function GetPlaceValueSet(ByVal Num As Byte) As String 
     Select Case Num 
      Case 0 
       Return "" 'Hundreds 
      Case 1 
       Return "Thousand" 
      Case 2 
       Return "Million" 
      Case 3 
       Return "Billion" 
      Case 4 
       Return "Trillion" 
      Case 5 
       Return "Quadrillion" 
      Case 6 
       Return "Quintillion" 
      Case 7 
       Return "Sextillion" 
      Case 8 
       Return "Septillion" 
      Case 9 
       Return "Octillion" 
      Case 10 
       Return "Nonillion" 
      Case 11 
       Return "octillion" 
      Case 12 
       Return "nonillion" 
      Case 13 
       Return "decillion" 
      Case 14 
       Return "undecillion" 
      Case 15 
       Return "dodecillion," 
      Case 16 
       Return "tredecillion" 
      Case 17 
       Return "quattuordecillion" 
      Case 18 
       Return "quindecillion" 
      Case 19 
       Return "sexdecillion" 
      Case 20 
       Return "septendecillion" 
      Case 21 
       Return "octodecillion" 
      Case 22 
       Return "novemdecillion" 
      Case 23 
       Return "vigintillion" 
      Case 24 
       Return "unvigintillion" 
      Case 25 
       Return "dovigintillion" 
      Case 26 
       Return "trevigintillion" 
      Case 27 
       Return "quattuorvigintillion" 
      Case 28 
       Return "quinvigintillion" 
      Case 29 
       Return "sexvigintillion" 
      Case 30 
       Return "septenvigintillion" 
      Case 31 
       Return "octovigintillion" 
      Case 32 
       Return "novemvigintillion" 
      Case 33 
       Return "trigintillion" 
      Case 34 
       Return "untrigintillion" 
      Case 35 
       Return "dotrigintillion" 
      Case 36 
       Return "tretrigintillion" 
      Case 37 
       Return "quattuortrigintillion" 
      Case 38 
       Return "quintrigintillion" 
      Case 39 
       Return "sextrigintillion" 
      Case 40 
       Return "septentrigintillion" 
      Case 41 
       Return "octotrigintillion" 
      Case Else 
       Throw New Exception 
     End Select 
    End Function 
End Class 

este momento está en VB.NET, pero funciona por completo. Es una forma. Número a Verbal. Maneja números de hasta 123 caracteres de largo, creo.

1

Aquí está mi solución espero que le ayudará

namespace ConsoleApplication3 
{ 

    class Program 
    { 


     static void Main(string[] args) 
     { 

      string s = Console.ReadLine(); 
      ConvertMyword(int.Parse(s)); 

      Console.Read(); 

     } 

     static void ConvertMyword(int number) 
     { 
      int flag = 0; 
      int lflag = 0; 
      string words = String.Empty; 
      string[] places = { "ones", "ten", "hundred", "thousand", "ten thousand", "lacs","tenlacs","crore","tencrore" }; 
      string rawnumber = number.ToString(); 
      char[] a = rawnumber.ToCharArray(); 
      Array.Reverse(a); 
      for (int i = a.Length - 1; i >= 0; i--) 
      { 
       if (i % 2 == 0 && i > 2) 
       { 
        if (int.Parse(a[i].ToString()) > 1) 
        { 
         if (int.Parse(a[i - 1].ToString()) == 0) 
         { 
          words = words + getNumberStringty(int.Parse(a[i].ToString())) + " " + places[i - 1] + " "; 
         } 
         else 
         { 
          words = words + getNumberStringty(int.Parse(a[i].ToString())) + " "; 
         } 
        } 
        else if (int.Parse(a[i].ToString()) == 1) 
        { 
         if (int.Parse(a[i - 1].ToString())== 0) 
         { 
          words = words +"Ten" + " "; 
         } 
         else 
         { 
          words = words + getNumberStringteen(int.Parse(a[i - 1].ToString())) + " "; 
         } 
         flag = 1; 
        } 
       } 
       else 
       { 
        if (i == 1 || i == 0) 
        { 
         if (int.Parse(a[i].ToString()) > 1) 
         { 
          words = words + getNumberStringty(int.Parse(a[i].ToString())) + " " + getNumberString(int.Parse(a[0].ToString())) + " "; 
          break; 
         } 
         else if (int.Parse(a[i].ToString()) == 1) 
         { 
          if (int.Parse(a[i - 1].ToString()) == 0) 
          { 
           words = words + "Ten" + " "; 
          } 
          else 
          { 
           words = words + getNumberStringteen(int.Parse(a[i - 1].ToString())) + " "; 
          } 

          break; 
         } 
         else if (int.Parse(a[i - 1].ToString()) != 0) 
         { 
          words = words + getNumberString(int.Parse(a[i - 1].ToString())) + " "; 
          break; 
         } 
         else 
         { 
          break; 
         } 
        } 
        else 
        { 
         if (flag == 0) 
         { 
          for(int l=i;l>=0;l--) 
          { 
           if (int.Parse(a[l].ToString())!=0) 
           { 
            lflag = 1; 
           } 
          } 
          if (lflag == 1 && int.Parse(a[i].ToString())!=0) 
          { 

            words = words + getNumberString(int.Parse(a[i].ToString())) + " " + places[i] + " "; 
            lflag = 0; 


          } 
          else if(lflag == 0) 
          { 
           // words = words + getNumberString(int.Parse(a[i].ToString())) + " " + places[i] + " "; 
           lflag = 0; 
           break; 
          } 

         } 
         else 
         { 
          words = words + " " + places[i] + " "; 
          flag = 0; 
         } 

        } 
       } 
      } 
      Console.WriteLine(words); 
     } 
     static string getNumberString(int num) 
     { 
      string Word = String.Empty; 
      switch (num) 
      { 
       case 1: 
        Word = "one"; 
        break; 
       case 2: 
        Word = "two"; 
        break; 

       case 3: 
        Word = "three"; 
        break; 

       case 4: 
        Word = "four"; 
        break; 

       case 5: 
        Word = "five"; 
        break; 

       case 6: 
        Word = "six"; 
        break; 
       case 7: 
        Word = "seven"; 
        break; 

       case 8: 
        Word = "eight"; 
        break; 

       case 9: 
        Word = "nine"; 
        break; 


      } 
      return Word; 
     } 
     static string getNumberStringty(int num) 
     { 
      string Word = String.Empty; 
      switch (num) 
      { 

       case 2: 
        Word = "twenty"; 
        break; 

       case 3: 
        Word = "thirty"; 
        break; 

       case 4: 
        Word = "fourty"; 
        break; 

       case 5: 
        Word = "fifty"; 
        break; 

       case 6: 
        Word = "sixty"; 
        break; 
       case 7: 
        Word = "seventy"; 
        break; 

       case 8: 
        Word = "eighty"; 
        break; 

       case 9: 
        Word = "ninty"; 
        break; 


      } 
      return Word; 
     } 
     static string getNumberStringteen(int num) 
     { 
      string Word = String.Empty; 
      switch (num) 
      { 
        case 1: 
        Word = "eleven"; 
        break; 
       case 2: 
        Word = "tewlve"; 
        break; 

       case 3: 
        Word = "thirteen"; 
        break; 

       case 4: 
        Word = "fourteen"; 
        break; 

       case 5: 
        Word = "fifteen"; 
        break; 

       case 6: 
        Word = "sixteen"; 
        break; 
       case 7: 
        Word = "seventeen"; 
        break; 

       case 8: 
        Word = "eighteen"; 
        break; 

       case 9: 
        Word = "ninteen"; 
        break; 


      } 
      return Word; 
     } 
    } 

} 
8

versión totalmente recursivo:

private static string[] ones = { 
    "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", 
    "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", 
}; 

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

private static string[] thous = { "hundred", "thousand", "million", "billion", "trillion", "quadrillion" }; 

public static string ToWords(decimal number) 
{ 
    if (number < 0) 
     return "negative " + ToWords(Math.Abs(number)); 

    int intPortion = (int)number; 
    int decPortion = (int)((number - intPortion) * (decimal) 100); 

    return string.Format("{0} dollars and {1} cents", ToWords(intPortion), ToWords(decPortion)); 
} 

private static string ToWords(int number, string appendScale = "") 
{ 
    string numString = ""; 
    if (number < 100) 
    { 
     if (number < 20) 
      numString = ones[number]; 
     else 
     { 
      numString = tens[number/10]; 
      if ((number % 10) > 0) 
       numString += "-" + ones[number % 10]; 
     } 
    } 
    else 
    { 
     int pow = 0; 
     string powStr = ""; 

     if (number < 1000) // number is between 100 and 1000 
     { 
      pow = 100; 
      powStr = thous[0]; 
     } 
     else // find the scale of the number 
     { 
      int log = (int)Math.Log(number, 1000); 
      pow = (int)Math.Pow(1000, log); 
      powStr = thous[log]; 
     } 

     numString = string.Format("{0} {1}", ToWords(number/pow, powStr), ToWords(number % pow)).Trim(); 
    } 

    return string.Format("{0} {1}", numString, appendScale).Trim(); 
} 

actual funciona hasta los miles de billones (escala corta). Se puede agregar soporte adicional (para números más grandes, o para el long scale) simplemente cambiando la variable thous.

Tal vez, innecesariamente complejo (el caso especial para cientos me molesta un poco), dado que la modificación de la versión no recursiva también es bastante simple.

+0

Esto es exactamente lo que necesitaba. Gracias –

36

Actualmente, la mejor y más robusta biblioteca para esto es definitivamente Humanizer. Es de código abierto y está disponible como una Nuget:

Console.WriteLine(4567788.ToWords()); // => four million five hundred and sixty-seven thousand seven hundred and eighty-eight 

También cuenta con una amplia gama de herramientas para resolver los pequeños problemas de cada aplicación tiene con string s, enum s, DateTime s, TimeSpan s y así sucesivamente, y es compatible con muchos idiomas diferentes.

Console.WriteLine(4567788.ToOrdinalWords().Underscore().Hyphenate().ApplyCase(LetterCasing.AllCaps)); // => FOUR-MILLION-FIVE-HUNDRED-AND-SIXTY-SEVEN-THOUSAND-SEVEN-HUNDRED-AND-EIGHTY-EIGHTH 
+2

Guau, eso es multilingüe: afrikaans, árabe, bengalí, brasileño portugués, holandés, inglés, farsi, finlandés, francés, alemán, hebreo, italiano, noruego, polaco, polaco, rumano, ruso, serbio, serbio, esloveno, español, ucraniano. Consulte en https://github.com/Humanizr/Humanizer/tree/dev/src/Humanizer/Localisation/NumberToWords –

+4

Respuesta infravalorada. Esta es la respuesta correcta a la pregunta. –

1

En caso de que alguien quiere una versión de JavaScript

Number.prototype.numberToWords = function() { 
    var unitsMap = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]; 
    var tensMap = ["zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]; 

    var num = this.valueOf(); 
    if (Math.round(num == 0)) { 
     return "zero"; 
    } 
    if (num < 0) { 
     var positivenum = Math.abs(num); 
     return "minus " + Number(positivenum).numberToWords(); 
    } 
    var words = ""; 
    if (Math.floor(num/1000000) > 0) { 
     words += Math.floor(num/1000000).numberToWords() + " million "; 
     num = Math.floor(num % 1000000); 
    } 
    if (Math.floor(num/1000) > 0) { 
     words += Math.floor(num/1000).numberToWords() + " thousand "; 
     num = Math.floor(num % 1000); 
    } 
    if (Math.floor(num/100) > 0) { 
     words += Math.floor(num/100).numberToWords() + " hundred "; 
     num = Math.floor(num % 100); 
    } 
    if (Math.floor(num > 0)) { 
     if (words != "") { 
      words += "and "; 
     } 
     if (num < 20) { 
     words += unitsMap[num]; 
     } 
     else { 
      words += tensMap[Math.floor(num/10)]; 
      if ((num % 10) > 0) { 
       words += "-" + unitsMap[Math.round(num % 10)]; 
      } 
     } 
    } 
    return words.trim(); 
} 
0

Esta clase convierte perfectamente su flotador o doble (hasta las 2 de precisión). Simplemente copie y pegue su IDE y vea el resultado.

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

La solución de @Hannele también es buena pero no tiene valor: 10 000, 100 000 – Aamol

0

Aunque esto es una especie de vieja pregunta, he implementado esta funcionalidad con enfoque más detallado

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: tengo interpolación de cadenas de usuario que sólo está disponible en 4.6.1

0

Solución que toma menos código.

La parte más importante es sólo líneas par:

static Func<long, string> remainder = t => t > 0 ? " " + ToEN(t) : ""; 

public static string ToEN(this long val, double d = 20, long th = 20) 
{ 
    switch ((long)d) 
    { 
     case 20: return val >= d ? ToEN(val, 1e2)    : en[val]; 
     case 100: return val >= d ? ToEN(val, 1e3, 100)  : en[val/10 * 10] + remainder(val % 10); 
     default: return val >= d ? ToEN(val, d * 1e3,(long)d) : ToEN(val/th) + " " + en[th] + remainder(val % th); 
    } 
} 

código completo está disponible aquí https://dotnetfiddle.net/wjr4hF

0

El siguiente código de aplicación de consola de C dará acepta un valor monetario en número hasta 2 decimales y las impresiones en inglés Puede usarlo como referencia para lograr sus resultados.

namespace ConsoleApplication2 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text.RegularExpressions; 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      bool repeat = true; 
      while (repeat) 
      { 
       string inputMonetaryValueInNumberic = string.Empty; 
       string centPart = string.Empty; 
       string dollarPart = string.Empty; 
       Console.Write("\nEnter the monetary value : "); 
       inputMonetaryValueInNumberic = Console.ReadLine(); 
       inputMonetaryValueInNumberic = inputMonetaryValueInNumberic.TrimStart('0'); 

       if (ValidateInput(inputMonetaryValueInNumberic)) 
       { 

        if (inputMonetaryValueInNumberic.Contains('.')) 
        { 
         centPart = ProcessCents(inputMonetaryValueInNumberic.Substring(inputMonetaryValueInNumberic.IndexOf(".") + 1)); 
         dollarPart = ProcessDollar(inputMonetaryValueInNumberic.Substring(0, inputMonetaryValueInNumberic.IndexOf("."))); 
        } 
        else 
        { 
         dollarPart = ProcessDollar(inputMonetaryValueInNumberic); 
        } 
        centPart = string.IsNullOrWhiteSpace(centPart) ? string.Empty : " and " + centPart; 
        Console.WriteLine(string.Format("\n\n{0}{1}", dollarPart, centPart)); 
       } 
       else 
       { 
        Console.WriteLine("Invalid Input.."); 
       } 

       Console.WriteLine("\n\nPress any key to continue or Escape of close : "); 
       var loop = Console.ReadKey(); 
       repeat = !loop.Key.ToString().Contains("Escape"); 
       Console.Clear(); 
      } 

     } 

     private static string ProcessCents(string cents) 
     { 
      string english = string.Empty; 
      string dig3 = Process3Digit(cents); 
      if (!string.IsNullOrWhiteSpace(dig3)) 
      { 
       dig3 = string.Format("{0} {1}", dig3, GetSections(0)); 
      } 
      english = dig3 + english; 
      return english; 
     } 
     private static string ProcessDollar(string dollar) 
     { 
      string english = string.Empty; 
      foreach (var item in Get3DigitList(dollar)) 
      { 
       string dig3 = Process3Digit(item.Value); 
       if (!string.IsNullOrWhiteSpace(dig3)) 
       { 
        dig3 = string.Format("{0} {1}", dig3, GetSections(item.Key)); 
       } 
       english = dig3 + english; 
      } 
      return english; 
     } 
     private static string Process3Digit(string digit3) 
     { 
      string result = string.Empty; 
      if (Convert.ToInt32(digit3) != 0) 
      { 
       int place = 0; 
       Stack<string> monetaryValue = new Stack<string>(); 
       for (int i = digit3.Length - 1; i >= 0; i--) 
       { 
        place += 1; 
        string stringValue = string.Empty; 
        switch (place) 
        { 
         case 1: 
          stringValue = GetOnes(digit3[i].ToString()); 
          break; 
         case 2: 
          int tens = Convert.ToInt32(digit3[i]); 
          if (tens == 1) 
          { 
           if (monetaryValue.Count > 0) 
           { 
            monetaryValue.Pop(); 
           } 
           stringValue = GetTens((digit3[i].ToString() + digit3[i + 1].ToString())); 
          } 
          else 
          { 
           stringValue = GetTens(digit3[i].ToString()); 
          } 
          break; 
         case 3: 
          stringValue = GetOnes(digit3[i].ToString()); 
          if (!string.IsNullOrWhiteSpace(stringValue)) 
          { 
           string postFixWith = " Hundred"; 
           if (monetaryValue.Count > 0) 
           { 
            postFixWith = postFixWith + " And"; 
           } 
           stringValue += postFixWith; 
          } 
          break; 
        } 
        if (!string.IsNullOrWhiteSpace(stringValue)) 
         monetaryValue.Push(stringValue); 
       } 
       while (monetaryValue.Count > 0) 
       { 
        result += " " + monetaryValue.Pop().ToString().Trim(); 
       } 
      } 
      return result; 
     } 
     private static Dictionary<int, string> Get3DigitList(string monetaryValueInNumberic) 
     { 
      Dictionary<int, string> hundredsStack = new Dictionary<int, string>(); 
      int counter = 0; 
      while (monetaryValueInNumberic.Length >= 3) 
      { 
       string digit3 = monetaryValueInNumberic.Substring(monetaryValueInNumberic.Length - 3, 3); 
       monetaryValueInNumberic = monetaryValueInNumberic.Substring(0, monetaryValueInNumberic.Length - 3); 
       hundredsStack.Add(++counter, digit3); 
      } 
      if (monetaryValueInNumberic.Length != 0) 
       hundredsStack.Add(++counter, monetaryValueInNumberic); 
      return hundredsStack; 
     } 
     private static string GetTens(string tensPlaceValue) 
     { 
      string englishEquvalent = string.Empty; 
      int value = Convert.ToInt32(tensPlaceValue); 
      Dictionary<int, string> tens = new Dictionary<int, string>(); 
      tens.Add(2, "Twenty"); 
      tens.Add(3, "Thirty"); 
      tens.Add(4, "Forty"); 
      tens.Add(5, "Fifty"); 
      tens.Add(6, "Sixty"); 
      tens.Add(7, "Seventy"); 
      tens.Add(8, "Eighty"); 
      tens.Add(9, "Ninty"); 
      tens.Add(10, "Ten"); 
      tens.Add(11, "Eleven"); 
      tens.Add(12, "Twelve"); 
      tens.Add(13, "Thrteen"); 
      tens.Add(14, "Fourteen"); 
      tens.Add(15, "Fifteen"); 
      tens.Add(16, "Sixteen"); 
      tens.Add(17, "Seventeen"); 
      tens.Add(18, "Eighteen"); 
      tens.Add(19, "Ninteen"); 
      if (tens.ContainsKey(value)) 
      { 
       englishEquvalent = tens[value]; 
      } 

      return englishEquvalent; 

     } 
     private static string GetOnes(string onesPlaceValue) 
     { 
      int value = Convert.ToInt32(onesPlaceValue); 
      string englishEquvalent = string.Empty; 
      Dictionary<int, string> ones = new Dictionary<int, string>(); 
      ones.Add(1, " One"); 
      ones.Add(2, " Two"); 
      ones.Add(3, " Three"); 
      ones.Add(4, " Four"); 
      ones.Add(5, " Five"); 
      ones.Add(6, " Six"); 
      ones.Add(7, " Seven"); 
      ones.Add(8, " Eight"); 
      ones.Add(9, " Nine"); 

      if (ones.ContainsKey(value)) 
      { 
       englishEquvalent = ones[value]; 
      } 

      return englishEquvalent; 
     } 
     private static string GetSections(int section) 
     { 
      string sectionName = string.Empty; 
      switch (section) 
      { 
       case 0: 
        sectionName = "Cents"; 
        break; 
       case 1: 
        sectionName = "Dollars"; 
        break; 
       case 2: 
        sectionName = "Thousand"; 
        break; 
       case 3: 
        sectionName = "Million"; 
        break; 
       case 4: 
        sectionName = "Billion"; 
        break; 
       case 5: 
        sectionName = "Trillion"; 
        break; 
       case 6: 
        sectionName = "Zillion"; 
        break; 
      } 
      return sectionName; 
     } 
     private static bool ValidateInput(string input) 
     { 
      return Regex.IsMatch(input, "[0-9]{1,18}(\\.[0-9]{1,2})?")) 
     } 
    } 
} 

3

Aquí está la versión española:

 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

realmente necesitaba esto para una aplicación que estoy trabajando, pero no estaba contento con cualquiera de las soluciones aquí. Para su información, esta solución aprovecha el soporte de C# 7.0 para funciones locales. También utilicé el nuevo separador de dígitos para hacer que los números más grandes sean más legibles.

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(); 
    }  
} 

La carne está en la última sobrecarga ToWords.

1

Se me encomendó crear una API WEB que convierta números en palabras usando C#.

Puede ser un número entero o con decimales en 48 horas.

La llamada procederá de una aplicación de front-end utilizando el método Ajax Post y devolverá el resultado convertido en la página web.

He compartido públicamente que el proyecto en GitHub para referencia: https://github.com/marvinglennlacuna/NumbersToWordsConverter.Api

Con el siguiente implementatation técnica en colocar:

  1. MVC estructurado
  2. API controlador
  3. Servicio
  4. Modelo
  5. Error al manejar
  6. pruebas unitarias utilizando MSTest
  7. cobertura de código - 98%
  8. Jquery

Y con la documentación técnica sobre la siguiente, así:

  1. Propósito
  2. Requisitos previos
  3. Requisitos functionl
  4. Diagrama de proceso y de salida

** Resultado través de la página Web (US-001) **

estadounidense-001 convertir números a través Palabras proceso de página Web

enter image description here

US-001 Convertir números en palabras a través de la página web de salida

enter image description here

Resultado través del cartero (US-002)

estadounidense-002 - Convertir números a las palabras por medio del proceso del cartero

enter image description here

de EE.UU. -002 - Convertir números en palabras a través del cartero salida

enter image description here

creo que es sólo vale la pena compartir una solución de trabajo en el caso de que lo necesite para referencia en la entrevista/código de prueba/escuela o sólo para la diversión.

Saludos, Marvin

Cuestiones relacionadas