java整数舍入(除法相关)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38532636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:23:58  来源:igfitidea点击:

java integer rounding (division related)

javaintegerroundingdivisiontruncation

提问by Keybounce

I have run into a surprise with integer division notrounding down as expected.

我遇到了一个惊喜,整数除法没有按预期四舍五入。

Simple code:

简单代码:

public class HelloMath {

    public static void main(String[] args) {
        for (int s=1; s< 20; s++)
        {
            int div = 1<<s;
            int res = (int) ((float)-8/ s);
            System.out.printf("Bit %d, result %d\n", s, res);
        }
    }

}

Even with the explicit (float) casts, the output is:

即使使用显式(浮点)强制转换,输出也是:

Bit 1, result -8
Bit 2, result -4
Bit 3, result -2
Bit 4, result -2
Bit 5, result -1
Bit 6, result -1
Bit 7, result -1
Bit 8, result -1
Bit 9, result 0
Bit 10, result 0
Bit 11, result 0
Bit 12, result 0
Bit 13, result 0
Bit 14, result 0
Bit 15, result 0
Bit 16, result 0
Bit 17, result 0
Bit 18, result 0
Bit 19, result 0

I was expecting -1 all the way down.

我一直期待-1。

The real code where this is happening does this:

发生这种情况的真实代码是这样的:

public static int fluidTo8th(int fluid)
{
    if (0 == fluid)
        return 0;   // Technically, this isn't needed :-).
    int wholePart = (fluid-1) * 8 / RealisticFluids.MAX_FLUID; // -1 gets rounding correct;
    // consider fluid of exactly 1/8th.
    return 1+wholePart;
}

RealisticFluids.MAX_FLUID has the value (1<<20). The code is supposed to take an input that is 1 to MAX_FLUID (0 should only happen if the input block is air), and return a number from 0 to 7 -- 1 to 1/8th max is 0, 1/8th +1 to 2/8th is 2, up to 7/8th + 1 to 8/8th is 7.

RealisticFluids.MAX_FLUID 具有值 (1<<20)。该代码应该采用 1 到 MAX_FLUID 的输入(只有当输入块是空气时才会出现 0),并返回一个从 0 到 7 的数字——1 到 1/8 的最大值是 0、1/8+1到 2/8th 是 2,到 7/8th + 1 到 8/8th 是 7。

I'm expecting integer math to round all fractions down. But that's not happening -- I wind up with off-by-one errors all over the place as 5.999 winds up becoming 6 instead of 5.

我期待整数数学将所有分数四舍五入。但这并没有发生——因为 5.999 最终变成了 6 而不是 5,所以我在整个地方都出现了一对一的错误。

  1. Where is this behavior documented?
  2. What's the easiest work-around to get the rounding down that I expected?
  1. 这种行为记录在哪里?
  2. 达到我预期的四舍五入的最简单的解决方法是什么?

(full code context: https://github.com/keybounce/Finite-Fluids/blob/master/src/main/java/com/mcfht/realisticfluids/Util.java)

(完整代码上下文:https: //github.com/keybounce/Finite-Fluids/blob/master/src/main/java/com/mcfht/realisticfluids/Util.java

回答by Solomon Slow

I'm expecting integer math to round all fractions down.

我期待整数数学将所有分数四舍五入。

First of all, you're not doing integer division: You're doing floating point division. (float)-8is a floating point expression. Therefore, the sin (float)-8/sgets promoted to (float) before the division happens.

首先,你不是在做整数除法:你在做浮点除法。 (float)-8是一个浮点表达式。因此,s(float)-8/s除法发生之前in被提升为 (float)。

Then the floating point result is converted to an int. Reuseman said that integer division rounds toward zero. Well, float->int conversion also rounds toward zero.

然后将浮点结果转换为 int。Reuseman 说整数除法会向零舍入。好吧,float->int 转换也会向零舍入。