为什么双精度的小数部分不显示 Console.Write,而它与小数一起显示
本文关键字:显示 一起 小数 Write Console 双精度 小数部 为什么 | 更新日期: 2023-09-27 18:37:22
请考虑以下代码:
decimal decimalVal = 4.00M;
double doubleVal = 5.00;
Console.Write(decimalVal);
Console.Write(doubleVal);
为什么decimalVal
小数点后面显示零,而doubleVal
小数点后面的零不显示?
您看到的差异是由于Console.Write()
的设计方式。
当你这样称呼Console.Write
时:
Console.Write(decimalVal);
Console.Write(doubleVal);
在幕后,它实际上是在调用ToString()
并传递给它您当前的文化,相当于这样:
Console.Write(decimalVal.ToString(Thread.CurrentThread.CurrentCulture));
Console.Write(doubleVal.ToString(Thread.CurrentThread.CurrentCulture));
这两行未指定格式,因此使用区域性的常规 ("G") 格式,如 Double.ToString()
和 Decimal.ToString()
的文档中所述。
Console.Write(decimalVal.ToString("G"));
Console.Write(doubleVal.ToString("G"));
那么"G"格式说明符输出什么?同样,从文档中:
如果需要,结果包含小数点,小数点后面的尾随零将被省略。如果存在精度说明符,并且结果中的有效位数超过指定的精度,则通过舍入删除多余的尾随数字。
但是,如果数字是十进制并且省略了精度说明符......保留尾随零。
(我的强调是加的)
所以最终结果是Console.Write()
输出...
您的
double
值,不带尾随零。带有尾随零的
decimal
值。
为"开发者的选择",但后来Raymond Chen和Jeff Mercado都评论了根本原因:
这是因为十进制会记住它有多少精度。 4.00M 和 4.0M 是不一样的。(尽管它们比较相等。转换为字符串可显示精度。双精度不跟踪精度。~雷蒙德
decimal
必须保持其所表示的值的精度。double
没有。当您定义带有 3 个有效数字的小数 ''4 时,这正是您得到的。双精度5.00
可以用精确的值表示5
。它有多少位小数未编码到该值中。~杰夫
此外,从十进制文档中:
比例因子还会保留十进制数中的任何尾随零。尾随零不会影响算术或比较运算中十进制数的值。但是,如果应用了适当的格式字符串,则 ToString 方法可能会显示尾随零。
("比例因子"是一个值,表示小数点的小数部分 - 小数点之后的部分。
这意味着,尽管 3.0m、3.00m 和 3.000000m 在比较时都被认为是相等的,但 Decimal
类型存储适当的比例因子以确保尾随零不会丢失。
这不适用于不保留前导零的Double
类型。但是,如果您有double
并希望确保至少显示几个零,则可以指定一种格式:
Console.Write(doubleVal.ToString("F2")); // outputs 5.00