58 votes

Comment puis-je convertir un entier en sa représentation verbale?

Existe-t-il une bibliothèque ou une classe / fonction que je peux utiliser pour convertir un entier en sa représentation verbale?

Exemple d'entrée: 4,567,788

Exemple de sortie: Four million, Five hundred sixty-seven thousand, seven hundred eighty-eight

Pour référence, j'utilise C # et .NET 3.5.

68voto

I3arnon Points 9498

Actuellement, la meilleure, la plus robuste des bibliothèques pour cela est sans aucun doute Humanizr . C'est une source ouverte et disponible sous forme de pépite:

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

Il propose également une large gamme d’outils permettant de résoudre les problèmes mineurs rencontrés dans chaque application avec string s, enum s, DateTime s, TimeSpan s et ainsi de suite, et prend en charge de nombreuses langues différentes.

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

28voto

Ruben Carreon Points 99

si vous utilisez le code trouvé dans: convertir des nombres en mots C # et que vous en avez besoin pour les nombres décimaux, voici comment procéder:

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

11voto

Hannele Points 2906

Version entièrement récursive:

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

Travaux en cours au quadrillion (échelle courte). Une prise en charge supplémentaire (pour les grands nombres ou pour l’ échelle longue ) peut être ajoutée simplement en modifiant la variable thous .

Peut-être, inutilement complexe (le cas particulier de centaines me gêne un peu), étant donné que la modification de la version non récursive est également assez simple.

1voto

Joe Meyer Points 839

http://www.exchangecore.com/blog/convert-number-words-c-sharp-console-application/ possède un script C # qui cherche à gérer de très grands nombres et de très petites décimales.

 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: code transféré depuis le blog

0voto

Mitch Points 37
 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
 

Désolé, c'est dans VB.NET, mais ça fonctionne complètement. C'est à sens unique. Nombre à verbal. Gère les chiffres jusqu'à 123 caractères, je crois.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X