用Java精确地乘以两个数字

Mik*_*ike 1 java bigdecimal

我正在寻找一种在Java中乘以两个浮点数的精确方法,并且我读到我应该使用BigDecimal,但它不能按预期工作.我究竟做错了什么?

我的代码:

BigDecimal a = new BigDecimal(3.53);
BigDecimal b = new BigDecimal(3.59);
BigDecimal c = a.multiply(b);

System.out.println(c);
Run Code Online (Sandbox Code Playgroud)

结果:

12.672699999999998796873512674210388041622697702955394242845497954075284496866515837609767913818359375
Run Code Online (Sandbox Code Playgroud)

预期结果:

12.6727
Run Code Online (Sandbox Code Playgroud)

Ell*_*sch 12

当您使用BigDecimal(double)构造函数时,它不能比a更精确double,String而是使用表单.喜欢,

BigDecimal a = new BigDecimal("3.53");
BigDecimal b = new BigDecimal("3.59");
BigDecimal c = a.multiply(b);
System.out.println(c);
Run Code Online (Sandbox Code Playgroud)

哪个输出

12.6727
Run Code Online (Sandbox Code Playgroud)

链接的Javadoc部分说 -

笔记:

  1. 这个构造函数的结果可能有点不可预测.有人可能会认为BigDecimal(0.1)在Java 中编写new 会创建一个BigDecimal完全等于0.1(未缩放的值为1,标度为1),但它实际上等于0.1000000000000000055511151231257827021181583404541015625.这是因为0.1不能精确地表示为double(或者,就此而言,作为任何有限长度的二进制分数).因此,传递给构造函数的值并不完全等于0.1,尽管有外观.

  2. String构造,在另一方面,是完全可以预测的:写作new BigDecimal("0.1")创建一个BigDecimal,它正好等于0.1,正如人们所期望的那样.因此,通常建议优先使用String构造函数.

  • @Mikemike:不要**将**转换成一个字符串.这仍然有很大的机会获得错误的价值观.**立即用琴弦开始**.不要使用双打.如果你使用双倍,你可能很幸运,并得到一个合理的结果.但是你很幸运.Double可以准确地表示一些十进制值,但不是大多数. (3认同)