Java整数除法对于负数不会给出向下取整

5
我试图使用Java的整数除法,据说它会向下取整。然而,它实际上是向零舍入而不是向下取整。
public class Main {
    public static void main(String[] args) {
        System.out.println(-1 / 100); // should be -1, but is 0
        System.out.println(Math.floor(-1d/100d)); // correct
    }
}

问题在于我不想转换为double/float,因为这样效率太低了。我正试图用一个方法 floorDivide(long a, long b) 来解决这个问题。我的代码如下:
static long floorDivide(long a, long b) {
    if (a < 0) {
        // what do I put here?
    }
    return a / b;
}

如何在不使用 double/float 的情况下完成此操作?


1
将你的 int 类型之一转换为 double 类型并没有任何低效之处。 - Zircon
7个回答

12

floorDiv() 方法在 Java.Math 中能够完美地达到你的要求。

static long floorDiv(long x, long y)

返回最大的(靠近正无穷大)长整型值,该值小于或等于代数商。


1

取绝对值,除以它自己,再乘以-1。

奇怪的错误。


9
不是Bug,计算商和余数有多种方法。向-1取整的是欧几里得除法,而Java使用的是截断除法。 - Jack
2
无法处理 -1 / 4 这样的内容。它会返回0,但我需要的是-1。 - AMACB

0

虽然有点晚,但您需要将参数转换为longdouble

int result = (int) Math.floor( (double) -1 / 5 );
// result == -1

这个方法对我来说非常优雅地解决了问题。


0

只需将两个整数相除,然后将结果减去1(如果分子和分母的绝对值不同)。例如,-3/3给出-1,这是正确答案,无需在除法中添加-1。


0

对于一般情况,我会像Frank Harper建议的那样使用floorDiv()

但请注意,当除数是2的幂时,通常会通过适当数量的位右移来替代除法,即

x / d

等同于

x >> p

当 p = 0,1,...,30 (或者对于 longs ,是 0,1,...,62),d = 2p 并且 x 是非负数。这不仅比普通除法更有效,而且在 x 为负数时也可以得到正确的结果(在数学意义上)。


0

你可以使用

  int i = (int) Math.round(doubleValToRound);

它将返回一个 double 值,你可以将其强制转换为 int,而不会丢失精度或影响性能(类型转换没有很大的计算成本)。

同时它等同于

 int a = (int) (doubleValToRound + 0.5);
 //in your case
 System.out.println((int) ((-1 / 100) + 0.5));

使用这个方法,您将不必进入繁琐和不必要的“if”指令。就像一套好衣服一样,它适用于任何时刻,并具有更高的可移植性,适用于其他语言。


0

这很丑,但满足不使用double / float的要求。实际上,你应该把它转换成double。

这里的逻辑是如果整数除法不能整除,则取负结果的floor。

static long floorDivide(long a, long b)
{
    if(a % b != 0 && ((a < 0 && b > 0) || (a > 0 && b < 0)))
    {
        return (a / b - 1);
    }
    else
    {
        return (a / b);
    }
}

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