整数除法代码为什么会给出错误的答案?

32

我在Java中进行了一个非常简单的除法运算(是产品数量/每小时生产量),但是每当我进行这个除法时,就会出现奇怪的错误:

float res = quantity / standard;

我尝试了上面的除法运算,使用了几个值,但每次都出现错误,然而我在其他地方尝试并正确的代码是:

世界各地均适用:

13.6 = 6800 / 500;

Java:

13.0 = 6800 / 500;

我已经研究了BigDecimal和BigInteger,但是我还没有找到使用它们进行此除法的方法,在Java中有没有其他方式可以避免精度误差?

任何帮助都将不胜感激。


9
“无论在世界上哪个地方”,你都不能重新分配字面值的值;-) - Kerrek SB
除非有特定需要使用float,否则应该使用double - starblue
4
“全球范围内”是否排除了C、C++? - djechlin
4个回答

82

你正在进行整数除法,这意味着你正在使用整数除法

在整数除法中,结果的小数部分被舍去。

尝试以下内容:

float res = (float) quantity / standard;
            ^^^^^^^

上述代码强制将分子视为 float,从而将分母提升为 float,执行浮点除法而不是整数除法。

请注意,如果你处理的是字面值,你可以改变

float f = 6800 / 500;

为了使分母成为浮点数,需要在后面添加f后缀:


float f = 6800f / 500;
              ^

3
另一种常见的方法是将分子或分母乘以1.0。顺便说一句,除非您真的关心节省4个字节,否则几乎没有理由使用float而不是double。 - Paul Tomblin
4
@Paul: 所以,除非...否则没有理由使用 int 而不是 long。 [:-) - user85421
@Carlos,也许不是在Java中(实际上,我不知道),但在C或C++中,int可能比long要快得多,而由于“数学协处理器”(一些人还记得这些是单独的芯片),doubles通常比floats更快,因为它们不必被向下转换。 - Paul Tomblin

4

如果您关注精度,我建议使用double,它具有超过两倍的精度数字。然而,浮点数只能准确表示0.5的幂或和的分数。这意味着0.6只是近似表示。但是适当的四舍五入可以解决这个问题。

double d = (double) 6800 / 500;

或者

double d = 6800.0 / 500;

双精度和单精度之间是否有性能差异?我已经做了一些轻松的阅读,可能会对内存使用有所关注,因为软件将部署在一台相当老的机器上。 - Julian C.
double类型使用4个字节的额外内存。如果内存非常紧张,可以考虑使用float类型,如果您有一百万个这样的数据,可能可以节省4MB的内存。如果您没有那么多数据,那么就不必担心了。 - Peter Lawrey

1
在我的情况下,我正在做这件事:

double a = (double) (MAX_BANDWIDTH_SHARED_MB/(qCount+1));

代替“正确”的:

double a = (double)MAX_BANDWIDTH_SHARED_MB/(qCount+1);

-1

嗨,试试这个,它可能有助于满足您的需求。

double percent=(7819140000l-3805200000l)*100f/7819140000l;

public String format_Decimal(double decimalNumber) {
  NumberFormat nf = NumberFormat.getInstance();
  nf.setMaximumFractionDigits(5);
  nf.setMinimumFractionDigits(2);
  nf.setRoundingMode(RoundingMode.HALF_UP);
  String x = nf.format(decimalNumber);
  return x;
 }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接