ToString的奇数十进制类型行为(IFormatProvider)
var numberFormat = new NumberFormatInfo(); numberFormat.NumberDecimalSeparator = "."; numberFormat.NumberDecimalDigits = 2; decimal a = 10.00M; decimal b = 10M; Console.WriteLine(a.ToString(numberFormat)); Console.WriteLine(b.ToString(numberFormat)); Console.WriteLine(a == b ? "True": "False");
在控制台中:10.00 10真
为什么会有所不同? 更重要的是,无论变量如何初始化,如何调用ToString()以确保相同的输出?
NumberDecimalDigits
属性与"F"
和"N"
标准格式字符串一起使用,而不是在没有格式字符串的情况下调用的ToString
方法。
您可以使用:
Console.WriteLine(a.ToString("N", numberFormat));
关于如何使其输出始终如一的问题已得到回答,但这就是为什么它们首先输出不同的原因:
decimal
值在内部包含比例和系数的字段。 在10M
的情况下,编码的值具有10的系数和0的标度:
10M = 10 * 10^0
在10.00M
的情况下,编码的值的系数为1000,比例为2:
10.00M = 1000 * 10^(-2)
你可以通过检查内存中的值来看到这一点:
unsafe { fixed (decimal* array = new decimal[2]) { array[0] = 10M; array[1] = 10.00M; byte* ptr = (byte*)array; Console.Write("10M: "); for (int i = 0; i < 16; i++) Console.Write(ptr[i].ToString("X2") + " "); Console.WriteLine(""); Console.Write("10.00M: "); for (int i = 16; i < 32; i++) Console.Write(ptr[i].ToString("X2") + " "); } }
输出
10M: 00 00 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 10.00M: 00 00 02 00 00 00 00 00 E8 03 00 00 00 00 00 00
(0xA为hex,0x3E8为hex为1000)
C#规范的2.4.4.3节概述了这种行为:
以M或m为后缀的实数是十进制类型。 例如,文字1m,1.5m,1e10m和123.456M都是十进制类型。 通过获取精确值将此文字转换为十进制值,并在必要时使用银行家舍入(第4.1.7节)舍入到最接近的可表示值。 除非值被舍入或值为零,否则将保留文字中明显的任何比例(在后一种情况下,符号和比例将为0)。 因此,将解析文字2.900m以形成带符号0,系数2900和比例3的小数。
试试这个:
Console.WriteLine(String.Format("{0:0.00}", a)); Console.WriteLine(String.Format("{0:0.00}", b));
输出将始终包含2个十进制大小写。 更多例子:
https://www.csharp-examples.net/string-format-double/
上述就是C#学习教程:ToString的奇数十进制类型行为(IFormatProvider)分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1013527.html