¿Por qué este código no imprime el mismo número? :
long long a, b; a = 2147483647 + 1; b = 2147483648; printf("%lld\n", a); printf("%lld\n", b);Sé que el número máximo de la variable int es 2147483647 porque la variable int tiene 4 bytes. Pero como sé, la variable long long es de 8 bytes, pero ¿por qué ese código actúa así?
2147483647 + 1 se evalúa como la suma de dos ints y, por lo tanto, se desborda.
2147483648 es demasiado grande para caber en un int y, por lo tanto, el compilador asume que es long (o long long en MSVC). Por lo tanto, no se desborda.
Para realizar la suma como un long long use el sufijo constante apropiado, es decir
a = 2147483647LL + 1;Porque el rango de int en C/C++ es -2147483648 a +2147483647 .
Entonces, cuando agrega 1 , desborda el límite máximo de int .
Para una mejor comprensión, suponga que todo el rango de int se coloca en un círculo en el orden correcto:
2147483647 + 1 == -2147483648 2147483647 + 2 == -2147483647 Si desea superar esto, intente usar long long en lugar de int .
Buena pregunta. Como dijeron otros, los números por defecto son int , por lo que su operación para a actúa en dos int s y se desborda. Traté de reproducir esto, y extendí un poco para convertir el número en una variable long long y luego le agregué el 1 , como el ejemplo c a continuación:
$ cat test.c #include <stdlib.h> #include <stdint.h> #include <stdio.h> void main() { long long a, b, c; a = 2147483647 + 1; b = 2147483648; c = 2147483647; c = c + 1; printf("%lld\n", a); printf("%lld\n", b); printf("%lld\n", c); } El compilador advierte sobre el desbordamiento por cierto, y normalmente debe compilar el código de producción con -Werror -Wall para evitar percances como este:
$ gcc -m64 test.c -o test test.c: In function 'main': test.c:8:16: warning: integer overflow in expression [-Woverflow] a = 2147483647 + 1; ^ Finalmente, los resultados de la prueba son los esperados ( int overflow en el primer caso, long long int en el segundo y tercero):
$ ./test -2147483648 2147483648 2147483648Otra versión de gcc advierte aún más:
test.c: In function 'main': test.c:8:16: warning: integer overflow in expression [-Woverflow] a = 2147483647 + 1; ^ test.c:9:1: warning: this decimal constant is unsigned only in ISO C90 b = 2147483648; ^ Tenga en cuenta también que técnicamente int y long y las variaciones de eso dependen de la arquitectura, por lo que su longitud de bit puede variar. Para los tipos de tamaño predecible, puede estar mejor con int64_t , uint32_t , etc., que se definen comúnmente en los compiladores modernos y los encabezados del sistema, por lo que sea cual sea el bitness para el que se crea su aplicación, los tipos de datos siguen siendo predecibles. Tenga en cuenta también que la impresión y el escaneo de dichos valores se componen de macros como PRIu64 etc.