Java 浮点和大十进制精度差

Java 浮点和大十进制精度差,java,floating-point,bigdecimal,Java,Floating Point,Bigdecimal,结果: 3.1 3.09999046325684 为什么它们的结果不同?我使用的是JDK1.7.0_033.1定义了一个double,而3.1f定义了一个float。您看到的是float表示该值的问题(float“仅”使用32位和双64位) 如果要准确地使用BigDecimal定义3.1,请使用String构造函数: public static void main(String[] args) { // TODO Auto-generated method stub BigDec

结果:
3.1
3.09999046325684


为什么它们的结果不同?我使用的是JDK1.7.0_03

3.1
定义了一个
double
,而
3.1f
定义了一个
float
。您看到的是
float
表示该值的问题(float“仅”使用32位和双64位)

如果要准确地使用
BigDecimal
定义
3.1
,请使用
String
构造函数:

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);

}
输出:

BigDecimal foo = new BigDecimal("3.1");
System.out.println(foo);

float
double
是具有不同精度的不同类型

BigDecimal.valueOf(double)可以纠正
double
中的表示错误,但不能纠正
float


除非有充分的理由,否则不要使用浮点。

问题是,对于浮点和双精度,数字的整数部分和小数部分分别使用32位和64位表示。当您试图表示一个分数值时,问题就出现了,这个分数值在二进制位中并没有精确的十进制表示

以.1为例,没有办法在基数2中准确地表示这一点,正如没有办法在基数10中准确地表示1/3一样

所以java使用了一些技巧,当你说:

3.1
它打印出正确的号码。但是,当您开始对这些值进行算术运算时,最终会出现舍入错误

BigDecimal是精确的,因为它使用不同的表示形式。它在内部存储一个BigInteger(它使用int[]表示巨大的数字)。然后,它使用一个精度值来告诉它这些整数中有多少位在小数点之后

例如,值3.1将用一个BigDecimal表示为31,精度=1 出于这个原因,BigDecimal不会受到相同的四舍五入问题,即浮点和双精度


但是,当使用浮点/双精度值初始化BigDecimal时,同样的舍入错误会进入BigDecimal实例。这就是为什么建议使用字符串来构造值。

由于新手犯了一个错误,我遇到了一个类似的问题,我想与大家分享一下:

float f = 3.1;
System.out.println(f);
这是给额外的精度,我不想和设置它的字符串修复它

然而,我正在这样做:

BigDecimal bd = new BigDecimal(float); 
新手犯的错误。我应该这么做的

BigDecimal bd = new BigDecimal(float);
bd.setScale(2, RoundingMode.HALF_UP);

我建议阅读。可能重复的可能重复的可能重复的那么,这是问题还是错误的浮动?我应该使用double来避免bug吗?哎呀,这些都不是bug。请阅读你问题下方其他人的建议。对这些问题的认识是编程101。也就是说,最好的方法是使用
String
,而不是
double
float
。谢谢大家,所有答案对我都很有帮助,但我只能选择一个最佳答案。我选择dacwe的答案,因为我只是一个简单的程序员,知道如何解决对我来说就足够了。
bd = bd.setScale(2, RoundingMode.HALF_UP);