4

我正在用 Java 构建一个 Web 应用程序,它可以进行数学运算并向用户显示步骤。在使用小数进行基本算术运算时,我经常会在准确的输出中弄得一团糟。

这是我的问题:

double a = 0.15;
double b = 0.01;
System.out.println(a - b);
// outputs 0.13999999999999999

float a = 0.15;
float b = 0.01;
System.out.println(a - b);
// outputs 0.14

float a = 0.16f;
float b = 0.01f;
System.out.println(a - b);
// outputs 0.14999999

double a = 0.16;
double b = 0.01;
System.out.println(a - b);
// outputs 0.15

complete两者的准确性都不可靠。是否有更精确的数字类,或者我应该将值四舍五入?

4

4 回答 4

6

您可以为此使用BigDecimal 。这很丑陋,但它有效:

BigDecimal a = new BigDecimal("0.15");
BigDecimal b = new BigDecimal("0.01");
System.out.println(a.subtract(b));

请务必使用 String 参数或valueOf方法构造它们,如下所示:

BigDecimal x = new BigDecimal("0.15");   // This is ok
BigDecimal x = BigDecimal.valueOf(0.15); // This is also ok

而不是双参数,像这样:

BigDecimal x = new BigDecimal(0.15); // DON'T DO THIS

因为如果您传入一个双精度数,您也会将双精度数的不准确性传递到新的 BigDecimal 实例中。如果您传入一个字符串,BigDecimal 将知道™ 并做正确的事™。

于 2012-08-29T07:16:39.537 回答
2

使用double. 如果你这样做,你可以获得 15 位数的准确度,这在大多数情况下已经足够了。

double a = 0.15;
double b = 0.01;
System.out.printf("%.2f%n", a - b);

double a2 = 0.16;
double b2 = 0.01;
System.out.printf("%.2f%n", a2 - b2);

印刷

0.14
0.15
于 2012-08-29T07:23:14.287 回答
1

BigDecimal怎么样?

但是,并非对所有分区都完全准确(例如 1/3)。为此,您需要分数,它不是 JDK 的一部分,但易于实现,例如作为两个整数(或 BigIntegers)。

于 2012-08-29T07:17:18.690 回答
0
  BigDecimal  a = new BigDecimal(".15");
  BigDecimal  b = new BigDecimal(".01"),
  BigDecimal  c = new BigDecimal(0);

  c = a.subtract(b);      
  System.out.println(c);
于 2012-08-29T07:23:31.450 回答