首页 新闻 会员 周边

请教各位大侠,关于C#中double数值问题!!!

0
悬赏园豆:5 [已解决问题] 解决于 2010-09-22 20:46

最近在看《C#本质论》,上面讲输出1.618033988749895就会1.61803398874989,最后一位会丢失。然后又Ronud-Trip格式化,讲了一个例子,代码如下:

const double num = 1.618033988749895;
            double re;
            string te;

            te = string.Format("{0}", num);
            re = double.Parse(te);
            System.Console.WriteLine("{0}: re != num", re != num);
           
            te = string.Format("{0:R}", num);
            re = double.Parse(te);
            System.Console.WriteLine("{0}: re = num",re == num);

运行结果:True:re !=num

               True: re== num

我就有疑问了,num被赋值后,输出时会丢失一位,即丢失5,那,num的值在存入计算机中时,是按15位的存的还是16位存的,也就是最后一位5有没有被存入?假如存入了5,那么是不是在一般情况下使用num的值时不包括5啊,比如输出num值时输出的数不包括5。

使用“{0:R}”时,会与原来数值相比较,原来的数是指存入的数还是还是代码中的数啊?

TonyL的主页 TonyL | 初学一级 | 园豆:195
提问于:2010-09-17 22:23
< >
分享
最佳答案
0

存进去了,只是读的时候没读出来

收获园豆:5
时间都去哪了 | 初学一级 |园豆:51 | 2010-09-18 22:36
其他回答(2)
0

你也说了,只有在输出的时候才少一位。那在内存中还是1.618033988749895,比的时候自然相等。

Astar | 园豆:40805 (高人七级) | 2010-09-18 11:21
0

添加

Console.WriteLine("num={0:R}", num);
Console.WriteLine("te={0}", te);
Console.WriteLine("re={0:R}", re);

True: re != num
num=1.6180339887498949
te=1.61803398874989
re=1.61803398874989
True: re = num
num=1.6180339887498949
te=1.6180339887498949
re=1.6180339887498949

可以看出,从num.ToString()的时候精度丢失了, 但是num.ToString("R")的时候没有丢失后面的两位。msdn:
http://msdn.microsoft.com/zh-cn/library/kfsatb94(VS.95).aspx

默认情况下,返回值只包含 15 位精度,但内部维护的最大精度是 17 位。如果此实例的值超过 15 位,则 ToString 返回 PositiveInfinitySymbolNegativeInfinitySymbol,而不是预期的数字。如果要求更高的精度,请用"G17"或"R"格式规范指定 format;前一种格式总是返回 17 位精度;而后一种格式在数字可以用 15 位精度表示时返回 15 位精度,在数字只能用最大精度表示时返回 17 位精度。

 

我想默认显示15位的原因是:一般来说,第17位是不可靠的,但第16位是可靠的,但是17位的不确定性进位会造成16位也不可靠,所以显示第15位

neutra | 园豆:450 (菜鸟二级) | 2010-09-19 00:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册