问题描述
浮点数采用二进制系统表示,在二进制中无法精确的表示0.1,0.3等。因此在浮点数进行相加减的时候,答案就很可能得到误差。为什么在下面中2.0-0.1却能得到精确的值1.9呢?
解决方案
解决方案二:
使用Decimal
解决方案三:
引用1楼rui888的回复:
使用Decimal
谢谢,我想知道的是原理,为什么
解决方案四:
解决方案五:
摘自:http://blog.csdn.net/bingjing12345/article/details/7907095对double不能算出精确值问题的思考我知道double型数据在内存的表示遵循IEEE标准,对于0.1,1.1,2.1等等很多数,不能被精确的表示为double数据只能被表示为最接近它的double值先来看一段程序doubled1=0.9;doubled2=0.1;doubled3=1.1;System.out.println(d1);System.out.println(d2);System.out.println(d3);输出为:0.90.11.1输出结果并没有变成我们想象的那种0.99999999999999或者1.10000000000000001这说明0.1,1.1本身就是double型最接近它们的值。再来看一段:System.out.println(5.0-4.1);System.out.println(5.0-3.1);System.out.println(5.0-2.1);System.out.println(5.0-1.1);System.out.println(5.0-0.1);System.out.println("******************");System.out.println(4.0-3.1);System.out.println(3.0-2.1);System.out.println(2.0-1.1);System.out.println(1.0-0.1);System.out.println("******************");System.out.println(4.0-0.1);System.out.println(3.0-0.1);System.out.println(2.0-0.1);System.out.println(1.0-0.1);输出结果:0.90000000000000041.92.93.94.9******************0.89999999999999990.89999999999999990.89999999999999990.9******************3.92.91.90.9这些结果开始时超出了我的想象从第一组数据看,相差大于1的,好像结果是对的,从第二组看,相差小于1的,结果居然也有对的,从第三组看,和0.1作差的全是对的。那么0.1跟1.1,2.1等等其它数有什么不同呢?相差大于1的时候结果怎么就变对了呢?问题就出现在0.1的IEEE表示上,因为它标准化的时候0.1要小数点被向右移位,而其它数小数点像左移这样0.1算的实际位数要比2.1,3.1等等其它数多几位,即0.1本身的double型表示比2.1中的那个0.1要精确。在做double型减法运算时,需要经过对阶,求和,右规,舍入(0舍1入)操作如5.0-0.1对阶需要移动5位,计算舍入后最后得出4.9。这个4.9中的0.9其实是一个不精确的数,但0.9比0.8999999999999或者0.90000000001更接近真实值。而5.0-4.1对阶时不需要移动,计算舍入后最后得出0.9000000000000004,这个数也不是一个精确值,只是因为真实值相对于0.9000000000000003或者0.9000000000000005,跟接近与0.9000000000000004.假如我的想法正确,那么就是对阶移动位数比较多时,计算机能得出跟数学计算一样的值,否则得出一个其他值。验证System.out.println(100.0-0.1);System.out.println(100.0-99.1);99.90.9000000000000057综上,结论是对的。同样的道理,假如某个数a大于2^54;因为double型的尾数是52位,加上标准化的一位共53位,那么将a转换为double型时,采用恒掉的方法,只能取前53位,又假如a的第54位为0,则(double)a+1==(double)a
解决方案六:
那不是精确值1.9,只是后面还有好多位,浮点数位数把后面的给截了,截剩下的1.9后面的都是0就给省略了;