修复没有BigDecimal的浮点精度问题

时间:2013-08-05 18:52:49

标签: java floating-point numbers floating-accuracy floating-point-precision

我对浮点值的舍入有问题。

以下代码给出了以下结果:

public class ProductOrder {

  public static void main(String[] args) {
    int q = 48;
    float p = 6.95f;

    System.out.println(q * p);
  }

------
Output: 333.59998

预期结果应为333.6

当我用49替换q然后它没关系,我得到340,55

4 个答案:

答案 0 :(得分:2)

正如已经指出的那样,BigDecimal设计用于精确处理短小数部分特别重要的情况,并且对于那些情况比任何二进制浮点格式要好得多。

第二个最佳解决方案是在整数分,并且仅在显示期间插入小数点。

如果必须使用二进制浮点数,double通常是比float更好的选择,除非你处理大量数字并且知道float有足够的精度。

对于输出,如果您希望得到一个结果,例如小数点后不超过2位小数,您可以使用DecimalFormat进行相应舍入:

import java.text.DecimalFormat;

public class Test {
  public static void main(String[] args) {
    DecimalFormat df = new DecimalFormat("#0.##");
    int q = 48;
    float p = 6.95f;
    System.out.println(df.format(q * p));
  }
}

打印333.6

答案 1 :(得分:0)

默认格式化产生的数字最少,这些数字是告知其邻居的数字所必需的。这意味着如果由于舍入错误导致结果稍微偏离,您将获得“丑陋”的输出。

解决这个问题的一种方法是使用精确算术(BigDecimal或整数算术)。另一种是对输出进行舍入,例如:

System.out.printf("%f", p*q);

答案 2 :(得分:0)

数字333.6不能完全表示为float,其精度最高为6位小数。当您尝试以太高的精度(8位数)打印时,显示了潜在的舍入错误。

double精度高达15位。

但是,正如其他人所指出的那样,如果您正在处理财务计算,则应该使用BigDecimal

作为参考,您可以使用IEEE-754 Floating-Point Conversion网站查看任何给定的十进制数字,确切地了解它在floatdouble中的表示方式。

答案 3 :(得分:-1)

这里的问题是浮点受浮点精度误差的影响。您可以使用double两倍的精度(最终仍然会出错,但它比使用float更准确。)

E.g。

public static void main(String[] args) {
    int q = 48;
    double p = 6.95;

    System.out.println(q * p);
}

This will give 333.6.