java整数舍入(与分部相关)

时间:2016-07-22 17:54:55

标签: java integer rounding division truncation

我遇到了整数除法而不是按预期四舍五入的惊喜。

简单代码:

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

}

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

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

我一直期待着-1。

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

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具有值(1 <&lt;&lt; 20)。 该代码应该采用1到MAX_FLUID的输入(0应该只在输入块是空的时候发生),并返回一个从0到7的数字 - 1到1/8最大值是0,1 / 8th +1至2/8为2,最高为7/8 + 1至8/8为7。

我期待整数数学将所有分数向下舍入。但事情并没有发生 - 我最终会出现各种各样的错误,因为5.999会变成6而不是5。

  1. 这种行为记录在哪里?
  2. 最简单的解决方法是什么,以达到我预期的四舍五入?
  3. (完整代码上下文:https://github.com/keybounce/Finite-Fluids/blob/master/src/main/java/com/mcfht/realisticfluids/Util.java

2 个答案:

答案 0 :(得分:7)

Java中的整数除法不会因为您理解而向下舍入(即更低的值)。在Java术语中,向下舍入表示rounding towards zero

Here is the relevant section from the JLS,明确指出

  

整数除法向0舍入。

获得所需舍入的最简单方法是进行浮点除法,然后使用Math.floor进行舍入。

int res = (int)Math.floor(-8F / s);

答案 1 :(得分:2)

  

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

首先,你没有进行整数除法:你正在进行浮点除法。 (float)-8是一个浮点表达式。因此,s中的(float)-8/s会在分割发生之前被提升为(浮动)。

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