关于java浮点型数据计算精确度的问题

时间:2023-01-08 09:33:42
如题,近期需要做一个对于数据要求特别精确的东西,但java对于浮点型小数的运算好像不是很精确,不知如何解决,望高手指教。
比如在java中 System.out.println(10000*1.005);时,竟然输出10049.99999999997
有什么好的处理办法请指教,不能用保留2位小数或者四舍五入的方法来实现,因为会影响到后边数据的计算,就只要实现10000*1.005直接等于10050.00的方式,而不是通过四舍五入或保留小数来实现,谢谢

21 个解决方案

#1


浮点数都会丢失精度
用BigDecimal吧
new BigDemial(10000).multiply(new BigDecimal(1.005))

#2


大数值 BigInteger 和 BigDecimal

#3


BigDecimal

#4


我用了BigDecimal后感觉好像还是没有达到效果,只不过相对更接近些,但后边还是有N多的小数位,比如10049.9999999874568798654532459789(我随便写的,大概就是这意思)
但我想要的是10050.00这个数值

#5


大数值 BigInteger 和 BigDecimal,这个好像不是很好用,在API文档中有详细介绍,你可以看看

#6


一旦涉及到浮点数,如果不做特别的算法处理,那么不精确几乎是肯定的,
这和浮点数的定义有关(IEEE standard 754)。

double的精度要比float高很多,通常的精度要求,double应该都能满足,
如果你要求完全不能损失精度,我估计你只能找一些特定的算法了。

或者使用数据库的number类型也是一个办法,oracle的number数据类型是精确的。

#7


我是个初学者,不过我记得float肯定会丢失精度的
我记得我编过一个扎金花游戏,里面随机产生数用的是int a=math.random()*9+1;
你看上去是可以产生1到10的随机数,但是其实他最大只能到9,就是因为random()产生的是float的数.他只能精确到0.99999,永远倒不了1

不过我觉得肯定是有办法的,但是我也不知道,等待高手!!!

#8


初学路过~~~~

#9


new BigDemial("10000").multiply(new BigDecimal("1.005"))

#10


BigDecimal

#11



        BigDecimal x = new BigDecimal("10000");
        BigDecimal y = new BigDecimal("1.005");
        BigDecimal z = x.multiply(y);
        z.setScale(2, RoundingMode.HALF_UP);




z就是精确解

z.setScale(2, RoundingMode.HALF_UP);就是lz后面所要的那个解

要注意的是构造BidDecimal,一定要用String去构造,千万不要用int,float,double去构造,哪怕new BigDecimal(0)也不可以,一定要用new BigDecimal("0")
涉及到精度问题.

精度上主要的问题,是在于
比如将十进制的0.1转化二进制数,结果是一个二进制的循环数,0.1并不能被二进制数精确表示,所以会出现楼主的问题

#12


学习了学习了学习了。

#13


建议使用BigDecimal

#14


学习!

#15


学习哈

#16


谢谢楼上各位的回复,我再试试BigDecimal,另外,不光是浮点型,double的也一样会有精度问题
比如:
double dbl1 = 10000;
double dbl2 = 1.005;
System.out.println(10000*1.005);
也是一样的10049.99999999997

#17


学习了

#18


BigInteger & BigDecimal

#19


BigDecimal(Double)构造器和BigDecimal(String)构造器,在执行精确小数的时候  一定要用BigDecimal(String)构造器,
BigDecimal(Double)构造器将用它的参数的精确度实例化,同样返回的是一个小数一堆的数
应该这样:
System.out.println(new BigDecimal("10000").multiply(new BigDecimal("1.005")));

#20


学习了,

#21


谢谢楼上的各位,问题果然解决,还真是要用BigDecimal(String)构造器,马上结贴给分 关于java浮点型数据计算精确度的问题

#1


浮点数都会丢失精度
用BigDecimal吧
new BigDemial(10000).multiply(new BigDecimal(1.005))

#2


大数值 BigInteger 和 BigDecimal

#3


BigDecimal

#4


我用了BigDecimal后感觉好像还是没有达到效果,只不过相对更接近些,但后边还是有N多的小数位,比如10049.9999999874568798654532459789(我随便写的,大概就是这意思)
但我想要的是10050.00这个数值

#5


大数值 BigInteger 和 BigDecimal,这个好像不是很好用,在API文档中有详细介绍,你可以看看

#6


一旦涉及到浮点数,如果不做特别的算法处理,那么不精确几乎是肯定的,
这和浮点数的定义有关(IEEE standard 754)。

double的精度要比float高很多,通常的精度要求,double应该都能满足,
如果你要求完全不能损失精度,我估计你只能找一些特定的算法了。

或者使用数据库的number类型也是一个办法,oracle的number数据类型是精确的。

#7


我是个初学者,不过我记得float肯定会丢失精度的
我记得我编过一个扎金花游戏,里面随机产生数用的是int a=math.random()*9+1;
你看上去是可以产生1到10的随机数,但是其实他最大只能到9,就是因为random()产生的是float的数.他只能精确到0.99999,永远倒不了1

不过我觉得肯定是有办法的,但是我也不知道,等待高手!!!

#8


初学路过~~~~

#9


new BigDemial("10000").multiply(new BigDecimal("1.005"))

#10


BigDecimal

#11



        BigDecimal x = new BigDecimal("10000");
        BigDecimal y = new BigDecimal("1.005");
        BigDecimal z = x.multiply(y);
        z.setScale(2, RoundingMode.HALF_UP);




z就是精确解

z.setScale(2, RoundingMode.HALF_UP);就是lz后面所要的那个解

要注意的是构造BidDecimal,一定要用String去构造,千万不要用int,float,double去构造,哪怕new BigDecimal(0)也不可以,一定要用new BigDecimal("0")
涉及到精度问题.

精度上主要的问题,是在于
比如将十进制的0.1转化二进制数,结果是一个二进制的循环数,0.1并不能被二进制数精确表示,所以会出现楼主的问题

#12


学习了学习了学习了。

#13


建议使用BigDecimal

#14


学习!

#15


学习哈

#16


谢谢楼上各位的回复,我再试试BigDecimal,另外,不光是浮点型,double的也一样会有精度问题
比如:
double dbl1 = 10000;
double dbl2 = 1.005;
System.out.println(10000*1.005);
也是一样的10049.99999999997

#17


学习了

#18


BigInteger & BigDecimal

#19


BigDecimal(Double)构造器和BigDecimal(String)构造器,在执行精确小数的时候  一定要用BigDecimal(String)构造器,
BigDecimal(Double)构造器将用它的参数的精确度实例化,同样返回的是一个小数一堆的数
应该这样:
System.out.println(new BigDecimal("10000").multiply(new BigDecimal("1.005")));

#20


学习了,

#21


谢谢楼上的各位,问题果然解决,还真是要用BigDecimal(String)构造器,马上结贴给分 关于java浮点型数据计算精确度的问题