欧几里得除法中的二进制补码运算符

3

https://math.stackexchange.com/questions/679146/euclidean-divison-program

这个问题并没有得到解答。

我了解到,给定两个整数a和b(其中b ≠ 0),存在唯一的整数q和r使得a = bq + r且0 ≤ r < |b|,其中|b|表示b的绝对值-定义欧几里得除法。

下面是一个相应的程序,实现了这个逻辑:

int ifloordiv(int n, int d){

if (n >= 0)
    return n / d;
else
    return ~(~n / d);
}

阅读上述代码后,我很容易理解if(n>=0){}块代码的逻辑,即我们正在进行实际除法而不是欧几里得除法。
但是,else{(n<0)}代码逻辑使用位补码运算符(~)对我来说并不明显,我无法理解使用~运算符的思考方法。通常,我们在想到除法时使用>>运算符。
我知道Java中~运算符是整数类型的1's补码运算符。
我的问题是:
我想了解思考方法,即如何考虑使用位补码运算符(~),以帮助您在n<0时执行欧几里得除法。因为对我来说使用~运算符并不明显。请帮助我调整我的方法。

这是用什么语言编写的?你提到了Java,但标记了C和C++。 - harold
1个回答

6

~n 表示 -n - 1

所以,~(~n / d) 表示 -((-n - 1) / d) - 1

n 为负数且 d 为正数时,这个表达式实际上是向下取整的除法(通常除法会向零取整,对于负数的情况则向上取整)。我无法解释为什么会这样。


如果你将一个正数和一个负数相除,在C90中,我认为舍入可能无法定义清楚,它可能会向上或向下舍入。我认为这种荒唐的问题在C99中得到了解决,因此在处理这些内容时最好使用现代的C编译器。 - Lundin
@Lundin 在C90中,除法的舍入是实现定义的。基本上,没有任何硬件平台会做出与后来在C99中标准化的不同的事情。因此,在C99中明显不兼容的规范加强,以及出于同样的原因,您使用C90编译器是完全安全的:除法是实现定义的,C90编译器实现不会将其定义为与C99中不同的内容。 - Pascal Cuoq
我正在继续使用immibis的数学关系来延续我之前的帖子链接 - overexchange

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