8

谁能解释为什么地球上这些“相同”的表达式会返回不同的值?

(new BigDecimal(String.valueOf(131.7d))).multiply(new BigDecimal(String.valueOf(0.95d))).doubleValue() = 125.115

(new BigDecimal(               131.7d )).multiply(new BigDecimal(               0.95d )).doubleValue() = 125.11499999999998

BigDecimal 在他们之间有什么不同?

4

2 回答 2

6

如果您查看API 文档

BigDecimal(double val)
          Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value.

相对

BigDecimal(String val)
          Translates the string representation of a BigDecimal into a BigDecimal.

这些其实不是一回事。在double构造函数中,它使用浮点数(本质上是不准确的)。在String构造函数中,它采用您提供的确切值,而不是进行浮点转换。所以这实际上意味着上面的构造函数不是“相同”的表达式

于 2013-03-28T15:25:51.593 回答
5

如果您阅读 API 文档,您会发现 tahtString.valueOf(dobule)用于Double.toString(double)格式化该值。这可能并不明显,但Double.toString(double)在将其格式化为字符串之前将值四舍五入:

m 或 a 的小数部分必须打印多少位?必须至少有一个数字来表示小数部分,除此之外,必须有尽可能多的数字,但只需要将参数值与相邻的 double 类型值唯一区分开来。也就是说,假设 x 是由该方法为有限非零参数 d 生成的十进制表示所表示的精确数学值。那么 d 必须是最接近 x 的 double 值;或者如果两个双精度值同样接近 x,则 d 必须是其中之一,并且 d 的有效位的最低有效位必须为 0。

结果是String.valueOf(131.7d)即使参数的确切值为 131.69999999999998863131622783839702606201171875,也会返回字符串“131.7”。这样做的原因是小数部分不能总是用二进制小数精确表示(与浮点数和双精度数一起使用)。

因此,newnew BigDecimal(String.valueOf(131.7))将创建一个精确值为 131.7 的 BigDecimal。new BigDecimal(131.7)将创建一个精确值为 131.69999999999998863131622783839702606201171875 的 BigDecimal。

于 2013-03-28T15:40:15.083 回答