¿Cuál es el valor máximo de una variable numérica de bash shell?

17

Tengo curiosidad por saber qué sucede cuando una variable numérica en bash se incrementa sin detenerla a propósito. ¿Qué tan grande puede ser el número? ¿Se desbordará y se volverá negativo y continuará incrementándose para siempre? ¿Se romperá y patinará hasta detenerse en algún momento?

Estoy usando un procesador AMD x86_64, pero también me gustaría escuchar respuestas de 32 bits, solo especifique de qué está hablando. Estoy ejecutando Fedora21 de 64 bits.

He buscado en Google por todas partes, pero no he encontrado este dato específico por alguna extraña razón. Parece que sería una información básica en todos los manuales y demás.

Máximo poder
fuente
3
¿Qué tal imprimir algunas potencias de 2 como titular:for i in {0..70}; do echo 2 to the power of $i = $((2**i)); done
mpy
1
Si desea números grandes, puede cambiar a ksharitmética de punto flotante, no a entero como bash: ksh -c 'echo $((2**1023))'8.98846567431157954e+307
jlliagre
Tendré en cuenta ksh si necesito punto flotante o valores en la estratosfera, el punto flotante puede ser bastante útil. Pero esta pregunta es simplemente para que conozca los límites de mi sistema, no es porque necesite superar sus límites. Haré algo como sugiere mpy, no comencé porque no quería arriesgarme a causar un bloqueo del sistema.
Max Power

Respuestas:

22

Puede reducirse a su versión de bash, su sistema operativo y su arquitectura de CPU. ¿Por qué no lo intentas tú mismo? Establezca una variable en (2 ^ 31) -1, luego increméntelo, configúrelo en 2 ^ 32, luego increméntelo, configúrelo en 2 ^ 64, luego increméntelo, etc.

Aquí, lo probé yo mismo en mi Core i7 Mac con OS X "El Capitan" v10.11.3, y parece que bash está usando enteros de 64 bits con signo.

$ uname -a
Darwin Spiff.local 15.3.0 Darwin Kernel Versión 15.3.0: jue 10 de diciembre 18:40:58 PST 2015; raíz: xnu-3248.30.4 ~ 1 / RELEASE_X86_64 x86_64
$ bash --version
bash --version
GNU bash, versión 3.2.57 (1) -release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.
PS
$ ((X = 2 ** 16)); echo $ X
65536 <- está bien, al menos UInt16
$ ((X = 2 ** 32)); echo $ X
4294967296 <- está bien, al menos UInt32
$ ((X = 2 ** 64)); echo $ X
0 <- Uy, no UInt64
$ ((X = (2 ** 63) -1)); echo $ X
9223372036854775807 <- está bien, al menos SInt64
$ ((X ++)); echo $ X
-9223372036854775808 <- desbordado y envuelto negativo. Debe ser SInt64
Spiff
fuente
3

Configuré un bucle. while return status is 0 increment a variable with addition and print the variable to stdout Lo comencé justo debajo de 2 ^ 31, lo dejé pasar 2 ^ 31 y 2 ^ 32 sin problemas, lo detuve y luego configuré el valor inicial a poco menos de 2 ^ 63. El resultado fue que pasó sin problemas de 9.22e18 a -9.22e18 y continuó incrementándose positivamente. (hacia cero)

Solo para comprobar que while [ $? -eq 0 ]realmente estaba usando el estado de salida de los comandos dentro del ciclo while, no estaba usando el estado de salida del script anterior o alguna rareza, también lo ejecuté con un comando adicional dentro del ciclo diseñado para crear una salida distinta de cero estado en incrementos particulares.

Por lo tanto, está firmado, se desplazará en lugar de detenerse en el valor máximo, y lo hace sin ningún mensaje de error. Por lo tanto, es posible terminar en un bucle verdaderamente infinito. No limita el hardware de 64 bits y el sistema operativo Linux de 64 bits a un antiguo estándar de 16 o 32 bits.

Máximo poder
fuente
2

bash usa un entero de 64 bits. Entonces, si aumenta después de que la variable alcance su número máximo, la variable se desbordará. A continuación se muestra mi prueba con int sin signo y entero con signo.

MAX_UINT = 18446744073709551615
MAX_INT = 9223372036854775807

$ printf "%llu\n" $((2**64))
0
$ printf "%llu\n" $((2**64-1))
18446744073709551615

$ printf "%lld\n" $((2**63-1))
9223372036854775807
$ printf "%lld\n" $((2**63))
-9223372036854775808
$ printf "%lld\n" $((2**64-1))
-1
PT Huynh
fuente
2
agregue un texto que explique cómo responde esto a la pregunta. Parece que está intentando demostrar los límites superiores a través del código. ¿Puede explicar por qué este código logrará el resultado requerido?
Sir Adelaide