在数学上,考虑这个问题的有理数
8725724278030350 / 2**48
Run Code Online (Sandbox Code Playgroud)
其中**
在分母表示取幂,即,分母是2
对48
次方.(分数不在最低方面,通过2可还原的)此数目是恰好作为表示的System.Double
.它的十进制扩展是
31.0000000000000'49'73799150320701301097869873046875 (exact)
Run Code Online (Sandbox Code Playgroud)
撇号不代表缺失的数字,而只是标记圆形到15的分数.将执行17位数字.
请注意以下内容:如果此数字四舍五入为15位,则结果为31
(后跟十三0
秒),因为下一个数字(49...
)以a开头4
(意味着向下舍入).但如果数字首先四舍五入为17位,然后四舍五入为15位,结果可能是31.0000000000001
.这是因为第一次舍入通过将49...
数字增加到50 (terminates)
(下一个数字73...
)而向上舍入,然后第二次舍入可能再次向上舍入(当中点舍入规则表示"从零开始舍入"时).
(当然,还有更多具有上述特征的数字.)
现在,事实证明.NET的这个数字的标准字符串表示是"31.0000000000001"
.问题:这不是一个错误吗?通过标准字符串表示,我们指的String
是由参数Double.ToString()
实例方法产生的,当然,该方法与生成的方法相同ToString("G")
.
需要注意的一个有趣的事情是,如果你投的上述号码System.Decimal
,然后你得到一个decimal
是31
准确!请参阅此Stack Overflow问题,以讨论将a转换Double
为Decimal
包含第一个舍入到15位的令人惊讶的事实.这意味着转换为Decimal
正确的舍入到15位数,而调用ToSting()
是不正确的.
总而言之,我们有一个浮点数,当输出给用户时,是31.0000000000001
,但当转换为Decimal …
也许我错过了一些东西,但float.ToString()
方法围绕数字,这让我很头疼.
看看下面的小代码:当输入12345678作为输入时,调试器中的浮点数是正确的但ToString
方法的输出是12345680(我试过的任何格式......)
Console.WriteLine("Please enter a float number");
float theFloat = float.Parse(Console.ReadLine());
Console.WriteLine(string.Format("You have entered {0}", theFloat.ToString("F")));
Run Code Online (Sandbox Code Playgroud)
并输出:
Please enter a float number
12345678
You have entered 12345680.00
Run Code Online (Sandbox Code Playgroud)
将非常感谢帮助!