Qual è il valore massimo di una variabile numerica della shell bash?


17

Sono curioso di sapere cosa succede quando una variabile numerica in bash viene incrementata senza fermarla di proposito. Quanto può arrivare il numero? Traboccerà e diventerà negativo e continuerà ad aumentare per sempre? Si romperà e si fermerà a un certo punto?

Sto usando un processore AMD x86_64, ma sarei felice di sentire anche le risposte a 32 bit, basta specificare di cosa stai parlando. Sto eseguendo Fedora21 64 bit.

Ho cercato su Google in lungo e in largo, ma non ho trovato questo bocconcino specifico per qualche strana ragione. Sembra che sarebbe un'informazione di base in tutti i manuali e così via.


3
Che ne dici di stampare alcuni poteri di 2 come antipasto:for i in {0..70}; do echo 2 to the power of $i = $((2**i)); done
mpy

1
Se vuoi numeri grandi, potresti passare a kshquale aritmetica in virgola mobile, non un numero intero come bash: ksh -c 'echo $((2**1023))'8.98846567431157954e+307
jlliagre

Terrò a mente ksh se ho bisogno di virgola mobile o valori nella stratosfera, il virgola mobile può essere abbastanza utile. Ma questa domanda è semplicemente per conoscere i limiti del mio sistema, non perché devo superare i suoi limiti. Farò qualcosa come suggerisce mpy, non ho iniziato perché non volevo rischiare di causare un crash del sistema.
Max Power

Risposte:


22

Potrebbe dipendere dalla versione di bash, dal sistema operativo in uso e dall'architettura della CPU. Perché non lo provi tu stesso? Impostare una variabile su (2 ^ 31) -1, quindi incrementarla, impostarla su 2 ^ 32, quindi incrementarla, impostarla su 2 ^ 64, quindi incrementarla, ecc.

Qui, l'ho appena provato sul mio Mac Core i7 con OS X "El Capitan" v10.11.3, e sembra che bash stia usando numeri interi a 64 bit firmati.

$ uname -a
Darwin Spiff.local 15.3.0 Darwin Kernel Versione 15.3.0: Gio 10 Dic 18:40:58 PST 2015; root: xnu-3248.30.4 ~ 1 / RELEASE_X86_64 x86_64
$ bash --version
bash: versione
GNU bash, versione 3.2.57 (1) -release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.
$
$ ((X = 2 ** 16)); echo $ X
65536 <- okay, almeno UInt16
$ ((X = 2 ** 32)); echo $ X
4294967296 <- okay, almeno UInt32
$ ((X = 2 ** 64)); echo $ X
0 <- oops, non UInt64
$ ((X = (2 ** 63) -1)); echo $ X
9223372036854775807 <- okay, almeno SInt64
$ ((X ++)); echo $ X
-9223372036854775808 <- traboccato e avvolto negativo. Deve essere SInt64

3

Ho creato un loop. while return status is 0 increment a variable with addition and print the variable to stdout L'ho avviato poco meno di 2 ^ 31, l'ho lasciato passare senza problemi 2 ^ 31 e 2 ^ 32, l'ho interrotto, quindi ho impostato il valore iniziale su 2 ^ 63. Il risultato fu che rotolò senza soluzione di continuità da 9,22e18 a -9,22e18 e continuò ad aumentare positivamente. (verso zero)

Solo per verificare che il mio while [ $? -eq 0 ]stesse effettivamente utilizzando lo stato di uscita dei comandi all'interno del ciclo while, non utilizzando lo stato di uscita dello script precedente o qualche stranezza, l'ho anche eseguito con un comando aggiuntivo all'interno del ciclo progettato per creare un'uscita diversa da zero stato a incrementi particolari.

Quindi è firmato, scorrerà anziché fermarsi al valore massimo e lo farà senza alcun messaggio di errore. Quindi è possibile finire in un ciclo davvero infinito. Non limita l'hardware a 64 bit e il sistema operativo Linux a 64 bit a un vecchio standard a 16 o 32 bit.


2

bash usa un numero intero a 64 bit. Quindi se aumenti dopo che la variabile ha raggiunto il numero massimo, la variabile trabocca. Di seguito è riportato il mio test con int senza segno e intero con segno.

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

2
si prega di aggiungere un testo che spiega come questo risponde alla domanda. Sembra che tu stia cercando di dimostrare i limiti superiori tramite il codice: puoi spiegare perché questo codice otterrà il risultato richiesto?
Sir Adelaide,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.