Por ejemplo, hay 3 variables de tipo largo, sumamos a y b y obtenemos s :
long a, b, s; ... s = a + b Ahora, ¿qué significa ((s^a) < 0 && (s^b) < 0) ?
Vi un cheque como este en el código fuente de 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); }Este código está mal.
Asumiendo las reglas habituales de complemento a 2 de XOR bit a bit para enteros con signo, entonces
(s^a) < 0 es el caso si s tienen sus bits de a establecidos en valores opuestos. Por lo tanto,
((s^a) < 0 && (s^b) < 0) indica que s tiene un signo diferente tanto de a como de b , que luego debe tener el mismo signo (pretendiendo que 0 es positivo). Si agregó dos números enteros de signo igual y obtuvo un resultado de signo diferente, debe haber habido un desbordamiento, por lo que se trata de una comprobación de desbordamiento.
Si asumimos que el desbordamiento con signo termina, entonces s tiene el signo opuesto de a exactamente cuando se produce b desbordamiento. Sin embargo, el desbordamiento firmado es un comportamiento indefinido. Calcular s ya está mal; necesitamos comprobar si se produciría el desbordamiento sin realizar realmente la operación.
Se supone que Python no debe hacer esto. Puede ver lo que se supone que debe hacer en el código fuente de Python 2 para 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) Se supone que debe enviarse a sin firmar para obtener un comportamiento de desbordamiento definido. La corrección de transmisión a sin firmar se introdujo en 5 lugares diferentes como resultado del problema 7406 en el rastreador de errores de Python, pero parece que se perdieron un lugar, o tal vez INPLACE_ADD se cambió desde entonces. He dejado un mensaje en el rastreador.
No veo cómo esto es posible.
Si (s^a) < 0 , entonces el bit de signo de s o a debe ser un 1, por lo que s o a (pero no ambos) deben ser negativos. Lo mismo para s y b . Entonces, o s es negativo y tanto a como b son positivos, o s es positivo y tanto a como b son negativos. Ambas situaciones parecen imposibles.
A menos que cuente el desbordamiento/subdesbordamiento de enteros, por supuesto.