For example, there are 3 variables of long type, we add a
and b
and get s
:
long a, b, s;
...
s = a + b
Now what does ((s^a) < 0 && (s^b) < 0)
mean?
I saw a check like this in the source code of 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);
}
The Bitwise Xor operation treats the sign bit as it would any other bit. If one or both inputs for a pixel location are negative, the output is negative; if both inputs are positive, the output is positive.
XOR Background As we can see, if both bits are similar, then the XOR equals to zero. Otherwise, the result equals to one. Put differently, the bitwise XOR operation equals zero in case the number of ones is even and equals one in case the number of ones is odd.
To find each bit of XOR just calculate number of 1's in the corresponding bits. If it is even or zero then that XOR'ed bit is 0. If it is odd then that XOR'ed bit is 1.
The XOR logic gate can be used as a one-bit adder that adds any two bits together to output one bit. For example, if we add 1 plus 1 in binary, we expect a two-bit answer, 10 (i.e. 2 in decimal). Since the trailing sum bit in this output is achieved with XOR, the preceding carry bit is calculated with an AND gate.
This code is wrong.
Assuming the usual 2's-complement rules of bitwise XOR for signed integers, then
(s^a) < 0
is the case if s
and a
have their sign bits set to opposite values. Thus,
((s^a) < 0 && (s^b) < 0)
indicates that s
has sign different from both a
and b
, which must then have equal sign (pretending 0 is positive). If you added two integers of equal sign and got a result of different sign, there must have been an overflow, so this is an overflow check.
If we assume that signed overflow wraps, then s
has opposite sign from a
and b
exactly when overflow has occurred. However, signed overflow is undefined behavior. Computing s
is already wrong; we need to check whether the overflow would occur without actually performing the operation.
Python isn't supposed to do this. You can see what it's supposed to do in the 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)
It's supposed to cast to unsigned to get defined overflow behavior. The cast-to-unsigned fix was introduced in 5 different places as a result of issue 7406 on the Python bug tracker, but it looks like they missed a spot, or perhaps INPLACE_ADD
was changed since then. I've left a message on the tracker.
I don't see how this is possible.
If (s^a) < 0
, then the sign bit of either s
or a
must be a 1, so either s
or a
(but not both) must be negative. Same for s
and b
. So either s
is negative and both a
and b
are positive, or s
is positive and both a
and b
are negative. Both situations seem impossible.
Unless you count integer overflow/underflow, of course.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With