将带小数(货币)的数字转换为单词

时间:2017-04-10 22:45:05

标签: c# numbers

我想将带小数(货币)的数字转换为单词

例如:12345.60 - >一万二千四百四十五美元六十美分

我从这里得到了这段代码 http://www.csharp-tutorials.info/2016/04/convert-numbers-to-words-in-c.html

 public static string NumberToWords(int number)
    {
        if (number == 0)
            return "zero";

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

        string words = "";

        if ((number / 1000000000) > 0)
        {
            words += NumberToWords(number / 1000000000) + " billion ";
            number %= 1000000000;
        }

        if ((number / 1000000) > 0)
        {
            words += NumberToWords(number / 1000000) + " million ";
            number %= 1000000;
        }

        if ((number / 1000) > 0)
        {
            words += NumberToWords(number / 1000) + " thousand ";
            number %= 1000;
        }

        if ((number / 100) > 0)
        {
            words += NumberToWords(number / 100) + " hundred ";
            number %= 100;
        }

        if (number > 0)
        {
            if (words != "")
                words += " ";

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

            if (number < 20)
                words += unitsMap[number];
            else
            {
                words += tensMap[number / 10];
                if ((number % 10) > 0)
                    words += "-" + unitsMap[number % 10];
            }
        }

        return words;
    }

它与整数完全正常,但如果输入双.. 它显示错误

因为它只接受int。

我尽我所知但我不能改变代码以获得我想要的东西..

5 个答案:

答案 0 :(得分:4)

问题是你在双打上使用modulo,这显然是不允许的。 您必须将Math.Floor(number)与浮点之前的部件的给定代码一起使用,并且浮点之后的部件使用number - Math.Floor(number)。其余部分实际上在您的代码示例中给出,只需在浮点之前的部分之后添加"Dollar",在浮点之后的部分之后添加"cents"。你的代码看起来很像:

    public static string NumberToWords(double doubleNumber)
    {
        var beforeFloatingPoint = (int) Math.Floor(doubleNumber);
        var beforeFloatingPointWord = $"{NumberToWords(beforeFloatingPoint)} dollars";
        var afterFloatingPointWord =
            $"{SmallNumberToWord((int) ((doubleNumber - beforeFloatingPoint) * 100), "")} cents";
        return $"{beforeFloatingPointWord} and {afterFloatingPointWord}";
    }

    private static string NumberToWords(int number)
    {
        if (number == 0)
            return "zero";

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

        var words = "";

        if (number / 1000000000 > 0)
        {
            words += NumberToWords(number / 1000000000) + " billion ";
            number %= 1000000000;
        }

        if (number / 1000000 > 0)
        {
            words += NumberToWords(number / 1000000) + " million ";
            number %= 1000000;
        }

        if (number / 1000 > 0)
        {
            words += NumberToWords(number / 1000) + " thousand ";
            number %= 1000;
        }

        if (number / 100 > 0)
        {
            words += NumberToWords(number / 100) + " hundred ";
            number %= 100;
        }

        words = SmallNumberToWord(number, words);

        return words;
    }

    private static string SmallNumberToWord(int number, string words)
    {
        if (number <= 0) return words;
        if (words != "")
            words += " ";

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

        if (number < 20)
            words += unitsMap[number];
        else
        {
            words += tensMap[number / 10];
            if ((number % 10) > 0)
                words += "-" + unitsMap[number % 10];
        }
        return words;
    }

答案 1 :(得分:1)

如果目标平台/语言是 .NET/C#,那么您可以使用 NumericWordsConversion nuget 包并根据您的要求进行自定义。示例代码如下:

using NumericWordsConversion;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CurrencyConverterCore
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Currency to words");
            decimal amount = 111100000.12M;

            List<CurrencyFormat> formats = new List<CurrencyFormat>();
            formats.Add(new CurrencyFormat { CurrencyCode = "USD", CurrencyName="United States Dollar", Culture=Culture.International, CurrencyUnit = "", SubCurrencyUnit = "cents" });
            formats.Add(new CurrencyFormat { CurrencyCode = "MYR", CurrencyName="Ringgit Malaysia", Culture = Culture.International, CurrencyUnit = "", SubCurrencyUnit = "cents" });
            formats.Add(new CurrencyFormat { CurrencyCode = "SGD", CurrencyName = "Singapore Dollar", Culture = Culture.International, CurrencyUnit = "", SubCurrencyUnit = "cents" });
            formats.Add(new CurrencyFormat { CurrencyCode = "INR", CurrencyName = "Indian Rupee", Culture = Culture.Hindi, CurrencyUnit = "rupee", SubCurrencyUnit = "paisa" });
            formats.Add(new CurrencyFormat { CurrencyCode = "THB", CurrencyName = "Thai Baht", Culture = Culture.International, CurrencyUnit = "", SubCurrencyUnit = "satang" });
            formats.Add(new CurrencyFormat { CurrencyCode = "BDT", CurrencyName = "Bangladesh Taka", Culture = Culture.Hindi, CurrencyUnit = "taka", SubCurrencyUnit = "paisa" });

            CurrencyWordsConverter converter = null;

            string currencyToConvert = "BDT";
            string words = "";
            var format = formats.Where(x => x.CurrencyCode == currencyToConvert).FirstOrDefault();

            if (format != null)
            {
                
                converter = new CurrencyWordsConverter(new CurrencyWordsConversionOptions()
                {
                    Culture = format.Culture,
                    OutputFormat = OutputFormat.English,
                    CurrencyUnitSeparator = "and",
                    CurrencyUnit = format.CurrencyUnit,
                    SubCurrencyUnit = format.SubCurrencyUnit,
                    EndOfWordsMarker = "only"
                });

                words = (format.CurrencyUnit == "" ? (format.CurrencyName + " ") : "") + converter.ToWords(amount);
            }
            else
            {
                converter = new CurrencyWordsConverter();
                words = converter.ToWords(amount);
            }


            

            Console.WriteLine(words);
            Console.ReadKey();

        }

        class CurrencyFormat
        {
            public string CurrencyCode { get; set; }
            public string CurrencyName { get; set; }
            public Culture Culture { get; set; }
            public string CurrencyUnit { get; set; }
            public string SubCurrencyUnit { get; set; }

        }
    }
}

答案 2 :(得分:0)

作为上述答案的补充,由于当今大多数系统已全球化,因此支持多种货币并根据国家/地区识别小数位的不同方式支持转换非常重要。我通过在json文件中为要支持的每种主要货币创建模板来解决此问题,然后使用与上面类似的代码(无需硬编码)从模板读取数据并进行相应转换。例如,下面的模板,让我知道是否有人需要代码。

USD到单词的Json模板

    {
    "currencyKey": "USD",
    "formatMainUnit": "{0} dollar",
    "formatDecimalUnit": "{0} cent",
    "joinMainAndDecimal": "and",
    "ifNoDecimalUnit": "",
    "formatForMinus": "minus {0}",
    "unitsMap": [ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", 
    "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"],
    "tensMap": [ "zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" ],
    "groupMap": [
        {"tenRaiseTo":9, "word":"billion"},
        {"tenRaiseTo":6, "word":"million"},
        {"tenRaiseTo":3, "word":"thousand"},
        {"tenRaiseTo":2, "word":"hundred"}
    ]
}

INR转换为单词的Json模板

{
    "currencyKey": "INR",
    "formatMainUnit": "{0} rupee",
    "formatDecimalUnit": "{0} paisa",
    "joinMainAndDecimal": "and",
    "ifNoDecimalUnit": "zero paisa",
    "formatForMinus": "minus {0}",
    "unitsMap": [ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", 
    "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"],
    "tensMap": [ "zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" ],
    "groupMap": [
        {"tenRaiseTo":7, "word":"crore"},
        {"tenRaiseTo":5, "word":"lak"},
        {"tenRaiseTo":3, "word":"thousand"},
        {"tenRaiseTo":2, "word":"hundred"}
    ]
}

泰铢到单词的Json模板

{
    "currencyKey": "THB",
    "formatMainUnit": "{0} baht",
    "formatDecimalUnit": "{0} satang",
    "joinMainAndDecimal": "and",
    "ifNoDecimalUnit": "No satang",
    "formatForMinus": "minus {0}",
    "unitsMap": [ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", 
    "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"],
    "tensMap": [ "zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" ],
    "groupMap": [
        {"tenRaiseTo":9, "word":"billion"},
        {"tenRaiseTo":6, "word":"million"},
        {"tenRaiseTo":3, "word":"thousand"},
        {"tenRaiseTo":2, "word":"hundred"}
    ]
}

答案 3 :(得分:0)

您的映射数组帮助启发了这一结果,但是我走了一条不同的路线来处理这些地点。对我来说效果很好。它适用于美国货币。需要使用几种扩展方法(即RemoveDoubleSpaces(),TryIntParse()),但是它们的作用是显而易见的。

    public static string ToVerbalCurrency(this double value)
    {
        var valueString = value.ToString("N2");
        var decimalString = valueString.Substring(valueString.LastIndexOf('.') + 1);
        var wholeString = valueString.Substring(0, valueString.LastIndexOf('.'));

        var valueArray = wholeString.Split(',');

        var unitsMap = new[] { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
        var tensMap = new[] { "", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };
        var placeMap = new[] { "", " thousand ", " million ", " billion ", " trillion " };

        var outList = new List<string>();

        var placeIndex = 0;

        for (int i = valueArray.Length - 1; i >= 0; i--)
        {
            var intValue = valueArray[i].TryIntParse();
            var tensValue = intValue % 100;

            var tensString = string.Empty;
            if (tensValue < unitsMap.Length) tensString = unitsMap[tensValue];
            else tensString = tensMap[(tensValue - tensValue % 10) / 10] + " " + unitsMap[tensValue % 10];

            var fullValue = string.Empty;
            if (intValue >= 100) fullValue = unitsMap[(intValue - intValue % 100) / 100] + " hundred " + tensString + placeMap[placeIndex++];
            else if (intValue != 0) fullValue = tensString + placeMap[placeIndex++];
            else placeIndex++;

            outList.Add(fullValue);
        }

        var intCentsValue = decimalString.TryIntParse();

        var centsString = string.Empty;
        if (intCentsValue < unitsMap.Length) centsString = unitsMap[intCentsValue];
        else centsString = tensMap[(intCentsValue - intCentsValue % 10) / 10] + " " + unitsMap[intCentsValue % 10];

        if (intCentsValue == 0) centsString = "zero";

        var output = string.Empty;
        for (int i = outList.Count - 1; i >= 0; i--) output += outList[i];
        output += " dollars and " + centsString + " cents";

        return output.RemoveDoubleSpaces();
    }

答案 4 :(得分:0)

您可以使用此 Nuget Libray : 例如 =>

using NumberToEnglishWordConverter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DigitConverter
{
class Program
{
    static void Main(string[] args)
    {
        var number = 2500;
        var result = new NumberToEnglishWordConverter.NumberToEnglishWordConverter().changeCurrencyToWords(number);
        // the result will be => Two Thousand Five Hundred
    }
}

}

结果应该是:2500 => 2500