我想将带有小数(货币)的数字转换为word
例: 12345.60 --> 12,345美元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。
我用我的知识尽了最大努力,但我不能改变代码来得到我想要的。
发布于 2017-04-11 08:00:13
问题是你在doubles上使用了模,这(显然)是不允许的。对于浮点之前的部分,必须对给定代码使用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;
}发布于 2019-02-25 12:47:40
作为上述答案的补充,由于目前大多数系统都是全球化的,因此支持多种货币并支持根据国家识别小数组的不同方式进行转换是很重要的。我通过在json文件中为我想支持的每种关键货币创建模板,然后使用类似于上面的代码(没有硬编码)来从模板中读取数据并进行相应的转换,从而解决了这个问题。模板的例子在下面,让我知道如果有人需要的代码。
将USD转换为words的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 to words的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"}
]
}使用上述模板将数字转换为单词的实际C#代码。注意:将自定义框架相关代码替换为您自己的实现(例如: CacheManager)
using System; using System.Collections.Generic; using System.IO;
namespace BF
{
public class CurrencyToWords
{
private CurrencyTemplate template;
private const string DEFAULT_TEMPLATE = "Default_To_Words";
public CurrencyToWords(string tplFile)
{
if (string.IsNullOrWhiteSpace(tplFile)) tplFile = DEFAULT_TEMPLATE;
//read the template
template = LoadTemplate(tplFile);
if (template == null && tplFile != DEFAULT_TEMPLATE)
{
//load default template
tplFile = DEFAULT_TEMPLATE;
template = LoadTemplate(tplFile);
}
if (template != null)
{
//set to cache
CacheManager.setCacheObject(tplFile, template, 1000);
}
}
private CurrencyTemplate LoadTemplate(string tplFile)
{
CurrencyTemplate result = (CurrencyTemplate)CacheManager.getCachedObject(tplFile);
if (result == null)
{
//load from file
string filePath = CoreConfig.ConstructConfigCurrencyTplPath(tplFile + ".json");
if (File.Exists(filePath))
{
string jsonMap = System.IO.File.ReadAllText(filePath);
result = new CurrencyTemplate();
result = (CurrencyTemplate)CommonConversions.DeserializeJSON(jsonMap, result.GetType());
}
}
return result;
}
public string ConvertToWords(decimal value)
{
if (template == null) return "";
decimal workingValue = Math.Abs(value);
decimal beforeFloatingPoint = Math.Floor(workingValue);
string beforeFloatingPointWord = string.Format(template.formatMainUnit, ConvertParts(beforeFloatingPoint, 0));
decimal afterFloatingPoint = Math.Floor((workingValue - beforeFloatingPoint) * 100);
string afterFloatingPointWord;
if (afterFloatingPoint == 0)
{
afterFloatingPointWord = template.ifNoDecimalUnit;
}
else
{
afterFloatingPointWord = string.Format(template.formatDecimalUnit, ConvertParts(afterFloatingPoint, 0));
}
string result;
if (string.IsNullOrWhiteSpace(afterFloatingPointWord))
{
result = beforeFloatingPointWord;
}
else
{
result = string.Format("{0} {1} {2}", beforeFloatingPointWord, template.joinMainAndDecimal, afterFloatingPointWord);
}
//if negative apply template for representing negative value
if (value < 0)
{
result = string.Format(template.formatForMinus, result);
}
return result;
}
private string ConvertParts(decimal value, int group)
{
var words = "";
CurrencyGroupMap map;
decimal groupRange;
decimal workingValue = Math.Floor(value);
for ( ; group < template.groupMap.Count; group++)
{
map = template.groupMap[group];
groupRange = (decimal) Math.Pow(10, map.tenRaiseTo);
if (Math.Floor(workingValue / groupRange) > 0)
{
if (words != "")
words += ", ";
words += string.Format("{0} {1}", ConvertParts(workingValue / groupRange, group + 1), map.word);
workingValue %= groupRange;
}
}
words = ConvertSmallNumbers(workingValue, words);
return words;
}
private string ConvertSmallNumbers(decimal value, string words)
{
if (value <= 0) return words;
if (words != "")
words += " ";
int index;
try
{
index = (int)value;
}
catch
{
index = 0;
}
if (index < 20)
words += template.unitsMap[index];
else
{
words += template.tensMap[index / 10];
if ((index % 10) > 0)
words += "-" + template.unitsMap[index % 10];
}
return words;
}
}
public class CurrencyTemplate
{
public string currencyKey;
public string formatMainUnit;
public string formatDecimalUnit;
public string joinMainAndDecimal;
public string ifNoDecimalUnit;
public string formatForMinus;
public List<string> unitsMap;
public List<string> tensMap;
public List<CurrencyGroupMap> groupMap;
}
public class CurrencyGroupMap
{
public int tenRaiseTo;
public string word;
}
}发布于 2021-04-08 11:42:24
如果目标平台/语言是.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; }
}
}
}https://stackoverflow.com/questions/43334034
复制相似问题