gpt4 book ai didi

c - 如果和和两个加数的按位异或均为负,这意味着什么?

转载 作者:太空狗 更新时间:2023-10-29 17:10:31 27 4
gpt4 key购买 nike

比如有3个long类型的变量,我们加上ab得到 s :

long a, b, s;
...
s = a + b

现在 ((s^a) < 0 && (s^b) < 0) 是做什么的什么意思?

我在 source code 中看到了这样一张支票Python 的:

    if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
/* INLINE: int + int */
register long a, b, i;
a = PyInt_AS_LONG(v);
b = PyInt_AS_LONG(w);
i = a + b;
if ((i^a) < 0 && (i^b) < 0)
goto slow_iadd;
x = PyInt_FromLong(i);
}

最佳答案

这段代码是错误的。

假设有符号整数按位异或的通常 2 的补码规则,则

(s^a) < 0

如果 sa 将它们的符号位设置为相反的值,就会出现这种情况。因此,

((s^a) < 0 && (s^b) < 0)

表示 sab 的符号不同,它们必须具有等号(假装 0 是正数)。如果你把两个等号的整数相加得到不同符号的结果,那肯定是溢出了,所以这就是溢出检查。

如果我们假设有符号溢出回绕,那么 s 恰好在发生溢出时与 ab 具有相反的符号。但是,有符号溢出是未定义的行为。计算 s 已经是错误的;我们需要在不实际执行操作的情况下检查是否会发生溢出。

Python 不应该这样做。你可以在 Python 2 source code for int.__add__ 中看到它应该做什么:

/* casts in the line below avoid undefined behaviour on overflow */
x = (long)((unsigned long)a + b);
if ((x^a) >= 0 || (x^b) >= 0)

它应该转换为 unsigned 以获得定义的溢出行为。由于 issue 7406,在 5 个不同的地方引入了 cast-to-unsigned 修复。在 Python 错误跟踪器上,但看起来他们错过了一个地方,或者 INPLACE_ADD 从那时起就被改变了。我已经在追踪器上留言了。

关于c - 如果和和两个加数的按位异或均为负,这意味着什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31040256/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com