问题起源:
System.out.println(2.0-1.1);
这个在java Puzzlers 一书中有关于此问题的描述.结果是0.8999999999999999.
原因是因为计算机2进制无法精确表示0.1问题引申:
System.out.println(2.0f-1.1f);
为什么采用float形式计算的时候,这个结果确又有一点点准确了呢?结果确实是0.9,虽然这个值也许是经过一系列不精确的数近似而来.问题:怎么解释2.0f-1.1f运算时候,没有出现精度问题.如果不是很清楚,说一下大概猜测.如果清楚,麻烦告之详由.如果能有辅证最好.谢谢了!与问题无关的:
1.会是因为float精度比double低,所以得到0.9这个近似值么?
2.知道float也会有精度问题,有人能给出一个float计算出现了如2.0-1.1这样的类似精度问题的例子么.
3.从网上搜索到一个答案是,计算机在进行运算的时候是double运算,然后把结果转为float的.确实(float)(2.0-1.1)这个结果是0.9 可是float与float计算应该不会转型吧.
4.希望有人帮我解释一下,尽量别用类似下面的回复.计算机精度问题.精确计算用BigDecimal啊.用printf控制输出.四舍五入输出.format输出.
System.out.println(2.0-1.1);
这个在java Puzzlers 一书中有关于此问题的描述.结果是0.8999999999999999.
原因是因为计算机2进制无法精确表示0.1问题引申:
System.out.println(2.0f-1.1f);
为什么采用float形式计算的时候,这个结果确又有一点点准确了呢?结果确实是0.9,虽然这个值也许是经过一系列不精确的数近似而来.问题:怎么解释2.0f-1.1f运算时候,没有出现精度问题.如果不是很清楚,说一下大概猜测.如果清楚,麻烦告之详由.如果能有辅证最好.谢谢了!与问题无关的:
1.会是因为float精度比double低,所以得到0.9这个近似值么?
2.知道float也会有精度问题,有人能给出一个float计算出现了如2.0-1.1这样的类似精度问题的例子么.
3.从网上搜索到一个答案是,计算机在进行运算的时候是double运算,然后把结果转为float的.确实(float)(2.0-1.1)这个结果是0.9 可是float与float计算应该不会转型吧.
4.希望有人帮我解释一下,尽量别用类似下面的回复.计算机精度问题.精确计算用BigDecimal啊.用printf控制输出.四舍五入输出.format输出.
double 运算该怎么理解呢?
通常不能产生精确的结果,可以找出一个用float运算,结果却不准确的例子么.(不要太大或者太小的运算)
所以,想找到为什么上面float运算结果是0.9.
或者找出一个float运算却明显出现精度问题的计算。
System.out.println(2-1.10001);
System.out.println((float)(2-1.10001));
System.out.println(2f-1.10001f);计算结果0.8999900000000001
0.89999
0.89998996
我先写出结论再结帖.我需要写出double的2.0的二进制表示方法,double的1.1表示方法.然后做普通减法,得出结果前几位.
然后是float 的2.0的二进制表示方法,float的1.1表示方法,然后做减法,得出结果.对比这两结果是否可以解释 2.0f-1.1f
进行对阶,相加.
突然木木的想起来.2的-8次.类似这样的值怎么算啊。用笔算么?计算机怎么算啊.计算器不支持.代码pow也不支持....
可是如上面的问题.为什么double不准确了.float却依然近似到了0.9
我们人算加减法,都有个公式之类的。10进制加法逢10进一之类的.
我只是想知道java里面,浮点数是怎么存储的(包括float和double),怎么做的加法.最后怎么把算出来的值表示出来.现在的进度是根据ieee 754存储的浮点数
对应java的float 按1,8,23位分成三段,double: 1 ,11 , 52
分别为符号位,指数,底数.
2.0f-1.1f 为例.2.0f和-1.1f经过对阶,相加.这个过程是怎么样的?怎么样模拟.加完得到的那个二进制数怎么还原为十进制?结果类似0.011001100000101转为10进制.怎么算?单纯的1*2的-2次 + 1*2的-3次 + ...
这样也不是一个精确的值.在哪一位开始舍去的?