public static void main(String[] args) {
// TODO Auto-generated method stub
BigDecimal foo,foo1;
foo=BigDecimal.valueOf(3.1);
foo1=BigDecimal.valueOf(3.1f);
System.out.println(foo);
System.out.println(foo1);
}
结果:
3.1
3.0999999046325684
为什么他们会有不同的结果?我正在使用JDK1.7.0_03
发布于 2012-07-19 17:32:49
3.1
定义一个double
,而3.1f
定义一个float
。您看到的是float
在表示该值时遇到的问题(float“只”使用32位和双64位)。
如果您想使用BigDecimal
准确地定义3.1
,请使用String
构造函数:
BigDecimal foo = new BigDecimal("3.1");
System.out.println(foo);
输出:
3.1
发布于 2012-07-19 17:34:20
float
和double
是具有不同精度的不同类型。
BigDecimal.valueOf(double)可以纠正double
中的表示错误,但不能纠正float
中的表示错误
除非你有非常充分的理由,否则我不会使用float
。
发布于 2012-07-19 21:17:28
问题是,对于浮点数和双精度数,分别使用32位和64位来表示数字的整数和小数部分。当你试图用二进制位来表示一个没有精确的十进制表示的小数值时,问题就来了。
以.1为例,没有办法精确地用基数2表示,就像没有办法精确地用基数10表示1/3一样。
所以java使用了一些技巧,所以当你说:
float f = 3.1;
System.out.println(f);
它会打印出正确的数字。但是,当您开始使用这些值进行算术运算时,最终会出现舍入误差。
BigDecimal是准确的,因为它使用了不同的表示。它在内部存储一个BigInteger (使用int[]来表示大数)。然后,它使用精确值告诉它这些整数位中有多少位在小数点之后。
例如,值3.1将在BigDecimal中表示为31,precision=1因此,BigDecimal不会遇到浮点数和双精度浮点数的相同舍入问题。
但是,当您使用浮点数/双精度值来初始化BigDecimal时,同样的舍入误差会使其进入BigDecimal实例。这就是为什么建议使用字符串来构造值的原因。
https://stackoverflow.com/questions/11557839
复制相似问题