带有clockwork模数语句的Java整数最大值测试返回错误值

时间:2015-09-22 01:57:11

标签: java math int modulus

在课堂上我们正在使用“顺时针”模数函数 - 也就是说,一个函数基本上与Math.floorMod(int a,int b)相同。

对于课程,我不能使用Math.floorMod(),我在研究了这个主题之后写了这个:

 /**
 * Computes {@code a} mod {@code b} as % should have been defined to work.
 *
 * @param a
 *            the number being reduced
 * @param b
 *            the modulus
 * @return the result of a mod b, which satisfies 0 <= {@code mod} < b
 * @requires b > 0
 * @ensures
 * 
 *          <pre>
 * 0 <= mod  and  mod < b  and
 * there exists k: integer (a = k * b + mod)
 *          </pre>
 */
public static int mod(int a, int b) {
    assert b > 0 : "Violation of: b > 0";
    return (((a % b) + b) % b);
}

这是我的问题。这个函数传递了我抛出的每一个案例,除了一个,其中a = 2和b = INTEGER.MAX_VALUE。

那应该返回2,就像floorMod那样,但是它返回0.无论如何我可以在不使用floorMod的情况下解决这个问题吗?

提前致谢。

2 个答案:

答案 0 :(得分:1)

((a % b) + b)  // this does 2 + INTEGER.MAX and leads to an overflow

您可以使用以下方法来处理此问题并保留int值:

public static int mod(int a, int b) {
    assert b > 0 : "Violation of: b > 0";
    return (int) (( (long) (a % b) + b) % b );
}

答案 1 :(得分:0)

如果您按照Javadoc中所述的Math.floorMod定义,则应返回a - (floorDiv(a, b) * b)

floorDiv(a, b)只有当除法结果为负且a/b不能被a整除时,才会得到与b不同的结果,在这种情况下,它会返回a/b - 1 1}}(例如floorDiv(-4, 3) == -2,而(-4 / 3) == -1)。

因此,如果按照此定义实施,则获得:

public static int mod(int a, int b) {
    assert b > 0 : "Violation of: b > 0";
    int floorDiv = a/b;
    if ((a < 0) && (a % b != 0))
        floorDiv--;
    return a - (floorDiv * b);
}
顺便说一下,这个实现是实际Math.floorMod实现的一个子集,它允许两个参数都是负数。