.NET 将数字转换为字符串表示形式(1 到 1、2 到 2 等...)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/794663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
.NET convert number to string representation (1 to one, 2 to two, etc...)
提问by Mike Cole
Is there a built in method in .NET to convert a number to the string representation of the number? For example, 1 becomes one, 2 becomes two, etc.
.NET 中是否有内置方法将数字转换为数字的字符串表示形式?例如,1 变成 1,2 变成 2,等等。
回答by Ryan Emerle
I've always been a fan of the recursive method
我一直是递归方法的粉丝
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);
}
回答by BenAlabaster
Ah, there may not be a class to do this, but there was a code golf question which I provided a C# example for:
啊,可能没有一个类可以做到这一点,但是有一个代码高尔夫问题,我提供了一个 C# 示例:
However, it's not the easiest to read and it only goes up to decimal.MaxValue, so I've written a new version that will go as high as you need to.
然而,它不是最容易阅读的,它只能达到decimal.MaxValue,所以我写了一个新版本,它可以达到你需要的高度。
I couldn't find any information regarding values higher than vigintillions, but if you append the values to the thou[] array, you can continue going up as far as you like. It still doesn't support fractions, but I'm thinking about adding that at some point.
我找不到有关高于 vigintillions 的值的任何信息,但是如果您将这些值附加到 thou[] 数组中,您可以继续往上走。它仍然不支持分数,但我正在考虑在某个时候添加它。
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();
}
I tested it using Decimal.MaxValue appended to itself to generate a large number of:
我使用附加到自身的 Decimal.MaxValue 对其进行了测试以生成大量:
seven octodecillion, nine hundred and twenty-two septendecillion, eight hundred and sixteen sexdecillion, two hundred and fifty-one quindecillion, four hundred and twenty-six quattuordecillion, four hundred and thirty-three tredecillion, seven hundred and fifty-nine duodecillion, three hundred and fifty-four udecillion, three hundred and ninety-five decillion, thirty-three nonillion, five hundred and seventy-nine octillion, two hundred and twenty-eight septillion, one hundred and sixty-two sextillion, five hundred and four quintillion, two hundred and sixty-four quadrillion, three hundred and thirty-seven trillion, five hundred and ninety-three billion, five hundred and forty-three million, nine hundred and fifty- thousand, three hundred and thirty-five
七八十进制、九百二十二七十进制、八百一十六十六进制、二百五十一五十进制、四百二十六十进制、四百三十三三进制、七百五十九十二进制、三一百五十四千分之一、三百九十五分、三十三分、五百七十九分、二百二十八分、一百六十二分、五百零四分、 264万亿、337万亿、5930亿、543亿、95万、335
回答by Kevin
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";
}
回答by Mike Cole
Here is the modified code I used:
这是我使用的修改后的代码:
//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);
}
回答by naasking
This thread was a great help. I like Ryan Emerle's solution the best for its clarity. Here's my version which I think makes the structure clear as day:
这个线程是一个很大的帮助。我最喜欢 Ryan Emerle 的解决方案,因为它的清晰度最高。这是我的版本,我认为它使结构清晰:
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);
}
}
回答by Jim Stevenson
Based on Ryan Emerle's solution, this adds dashes at the correct locations, does not include trailing spaces, does not pluralize numbers, and properly handles an input of zero (0):
基于 Ryan 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;
}
回答by Ryan Penfold
Here's my refined version of the first answer. I hope it's useful.
这是我对第一个答案的精炼版本。我希望它有用。
/// <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();
}
回答by i3arnon
There's no built in solution in .net, but there are good libraries around. The best currently is definitely Humanizr:
中没有内置解决方案.net,但周围有很好的库。目前最好的绝对是Humanizr:
Console.WriteLine(794663.ToWords()); // => seven hundred and ninety-four thousand six hundred and sixty-three
It also supports ordinal, and roman representations:
它还支持序数和罗马表示:
Console.WriteLine(794663.ToOrdinalWords()); // => seven hundred and ninety-four thousand six hundred and sixty third
Console.WriteLine(794.ToRoman()); // => DCCXCIV
Humanizralso has a wide range of tools regarding string, DateTime, TimeSpanand so forth.
Humanizr也有关于各种各样的工具string,DateTime,TimeSpan等等。
Console.WriteLine(794.Seconds().Humanize().Underscore().Hyphenate()); // => 13-minutes
回答by BobbyShaftoe
A conversion from integer to long form English... I could write that ;-)is a pretty good article on the topic:
从整数到长格式英语的转换……我可以写成 ;-)是一篇关于该主题的非常好的文章:
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;
}
}
回答by Hussein Nasser
Another naasking, version in VB.NET if any one is interested! Had to use the floor function to round properly..
另一个 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

