我有一些集合返回的字段
2.4200
2.0044
2.0000
我想要类似的结果
2.42
2.0044
2
我尝试使用String.Format
,但是它返回2.0000
并将其设置为也N0
舍入其他值。
String.Format()
用'G'应该可以得到您想要的。.我已经用标准数字格式的链接更新了我的答案。非常好用。
ToString
函数相比,它可能会花费更少的性能(大量记录的间隔)。
我有一些集合返回的字段
2.4200
2.0044
2.0000
我想要类似的结果
2.42
2.0044
2
我尝试使用String.Format
,但是它返回2.0000
并将其设置为也N0
舍入其他值。
String.Format()
用'G'应该可以得到您想要的。.我已经用标准数字格式的链接更新了我的答案。非常好用。
ToString
函数相比,它可能会花费更少的性能(大量记录的间隔)。
Answers:
如果输入是字符串,这不是那么简单吗?您可以使用以下之一:
string.Format("{0:G29}", decimal.Parse("2.0044"))
decimal.Parse("2.0044").ToString("G29")
2.0m.ToString("G29")
这应该适用于所有输入。
更新检查标准数字格式,我必须将docs明确指出的精度说明符设置为29:
但是,如果数字为小数并且省略了精度说明符,则始终使用定点表示法并保留尾随零。
当心值,例如0.000001。G29格式将以最短的方式显示它们,因此它将切换为指数表示法。
string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))
结果将为“ 1E-08”。
我遇到了同样的问题,但是在我无法控制字符串输出的情况下,该问题由图书馆负责。在研究了Decimal类型的实现的详细信息之后(请参见http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx),我想到了一个巧妙的技巧(此处是扩展名)方法):
public static decimal Normalize(this decimal value)
{
return value/1.000000000000000000000000000000000m;
}
小数的指数部分减少到所需的大小。在输出的十进制上调用ToString()将写入数字而没有任何尾随的0。例如
1.200m.Normalize().ToString();
1
后跟33个0
-s,但这会创建decimal
与29个数字(1个1
和28个0
-s)完全相同的实例。就像@ThomasMaterna在他的评论中所说。没有System.Decimal
可以(与领先的数字大于数量已超过29倍的数字79228...
只能有28的总数字)。如果您想要更多的尾随零,请乘以1.000...m
而不是除。此外,Math.Round
可以斩零一些零,例如Math.Round(27.40000m, 2)
给27.40m
,所以只剩下一个零。
我认为使用“ 自定义数字格式字符串”更安全。
decimal d = 0.00000000000010000000000m;
string custom = d.ToString("0.#########################");
// gives: 0,0000000000001
string general = d.ToString("G29");
// gives: 1E-13
我使用此代码来避免使用“ G29”科学计数法:
public static string DecimalToString(this decimal dec)
{
string strdec = dec.ToString(CultureInfo.InvariantCulture);
return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}
编辑:使用系统CultureInfo.NumberFormat.NumberDecimalSeparator:
public static string DecimalToString(this decimal dec)
{
string sep = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
string strdec = dec.ToString(CultureInfo.CurrentCulture);
return strdec.Contains(sep) ? strdec.TrimEnd('0').TrimEnd(sep.ToCharArray()) : strdec;
}
Culture.NumberFormat.NumberDecimalSeparator
使用井号(#
)符号仅在必要时显示尾随0。请参阅下面的测试。
decimal num1 = 13.1534545765;
decimal num2 = 49.100145;
decimal num3 = 30.000235;
num1.ToString("0.##"); //13.15%
num2.ToString("0.##"); //49.1%
num3.ToString("0.##"); //30%
num1.ToString("0.##")
应返回13.1534545765
(无变化),因为没有任何尾随零。
我从http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/找到了一个优雅的解决方案
基本上
decimal v=2.4200M;
v.ToString("#.######"); // Will return 2.42. The number of # is how many decimal digits you support.
v
是0m
,则代码的结果为空字符串而不是"0"
。
这是一种非常低级的方法,但是我相信这将是仅通过使用快速整数计算(而没有慢速字符串解析和区域性敏感方法)才是性能最高的方法:
public static decimal Normalize(this decimal d)
{
int[] bits = decimal.GetBits(d);
int sign = bits[3] & (1 << 31);
int exp = (bits[3] >> 16) & 0x1f;
uint a = (uint)bits[2]; // Top bits
uint b = (uint)bits[1]; // Middle bits
uint c = (uint)bits[0]; // Bottom bits
while (exp > 0 && ((a % 5) * 6 + (b % 5) * 6 + c) % 10 == 0)
{
uint r;
a = DivideBy10((uint)0, a, out r);
b = DivideBy10(r, b, out r);
c = DivideBy10(r, c, out r);
exp--;
}
bits[0] = (int)c;
bits[1] = (int)b;
bits[2] = (int)a;
bits[3] = (exp << 16) | sign;
return new decimal(bits);
}
private static uint DivideBy10(uint highBits, uint lowBits, out uint remainder)
{
ulong total = highBits;
total <<= 32;
total = total | (ulong)lowBits;
remainder = (uint)(total % 10L);
return (uint)(total / 10L);
}
a
和b
)相除。但是,后来我发现了这个令人惊讶的简单解决方案,它也轻松击败了您和我提出的性能明智的解决方案。
这将起作用:
decimal source = 2.4200m;
string output = ((double)source).ToString();
或者,如果您的初始值为string
:
string source = "2.4200";
string output = double.Parse(source).ToString();
请注意此评论。
double.ToString
默认情况下cuz 会删除尾随零。
取决于您的数字代表什么以及您要如何管理值:它是一种货币,需要四舍五入或截断,仅需要显示才需要四舍五入?
如果要考虑显示格式,则数字为x.ToString(“”)
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx和
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
如果只是四舍五入,请使用需要MidPointRounding重载的Math.Round重载
http://msdn.microsoft.com/en-us/library/ms131274.aspx)
如果您从数据库获取值,请考虑使用转换而不是转换:double value =(decimal)myRecord [“ columnName”];
您可以设置为:
decimal decNumber = 23.45600000m;
Console.WriteLine(decNumber.ToString("0.##"));
尝试做更友好的DecimalToString解决方案(https://stackoverflow.com/a/34486763/3852139):
private static decimal Trim(this decimal value)
{
var s = value.ToString(CultureInfo.InvariantCulture);
return s.Contains(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator)
? Decimal.Parse(s.TrimEnd('0'), CultureInfo.InvariantCulture)
: value;
}
private static decimal? Trim(this decimal? value)
{
return value.HasValue ? (decimal?) value.Value.Trim() : null;
}
private static void Main(string[] args)
{
Console.WriteLine("=>{0}", 1.0000m.Trim());
Console.WriteLine("=>{0}", 1.000000023000m.Trim());
Console.WriteLine("=>{0}", ((decimal?) 1.000000023000m).Trim());
Console.WriteLine("=>{0}", ((decimal?) null).Trim());
}
输出:
=>1
=>1.000000023
=>1.000000023
=>
非常简单的答案是使用TrimEnd()。结果是这样
double value = 1.00;
string output = value.ToString().TrimEnd('0');
输出为1如果我的值为1.01,则我的输出为1.01
value = 100
呢?
以下代码可用于不使用字符串类型:
int decimalResult = 789.500
while (decimalResult>0 && decimalResult % 10 == 0)
{
decimalResult = decimalResult / 10;
}
return decimalResult;
返回789.5
截断尾随零非常简单,请使用双工强制转换:
decimal mydecimal = decimal.Parse("1,45000000"); //(I)
decimal truncate = (decimal)(double)mydecimal; //(II)
(I)->从任何字符串源解析十进制值。
(II)->第一:强制转换为两倍以删除尾随零。第二:其他类型转换为十进制,因为不存在从十进制到双精度的隐式转换,反之亦然)
试试这个代码:
string value = "100";
value = value.Contains(".") ? value.TrimStart('0').TrimEnd('0').TrimEnd('.') : value.TrimStart('0');
这样尝试
string s = "2.4200";
s = s.TrimStart('0').TrimEnd('0', '.');
然后将其转换为浮点
subString()
方法,但是根据此处发布的问题,我没有看到类似的任何要求=)
"12300.00"
将被精简为"123"
。似乎不希望出现的另一个效果是,某些数字"0.00"
会一直修剪到空字符串""
(尽管此数字是特殊的情况,是整数“ 10.0的倍数”)。