Berapa nilai maksimum variabel shell bash numerik?

17

Saya ingin tahu apa yang terjadi ketika variabel numerik di bash dinaikkan tanpa sengaja menghentikannya. Seberapa besar angka yang didapat? Apakah akan meluap dan menjadi negatif dan terus bertambah selamanya? Apakah akan pecah dan tergelincir berhenti di beberapa titik?

Saya menggunakan prosesor AMD x86_64, tetapi saya akan senang mendengar jawaban 32bit juga, cukup tentukan yang Anda bicarakan. Saya menjalankan Fedora21 64bit.

Saya sudah googled jauh dan luas tetapi belum menemukan berita gembira khusus ini untuk beberapa alasan aneh. Sepertinya itu akan menjadi informasi dasar dalam semua manual dan semacamnya.

Kekuatan penuh
sumber
3
Bagaimana kalau mencetak beberapa kekuatan 2 sebagai starter:for i in {0..70}; do echo 2 to the power of $i = $((2**i)); done
mpy
1
Jika Anda menginginkan angka besar, Anda dapat beralih ke ksharitmatika floating point, bukan bilangan bulat seperti bash: ksh -c 'echo $((2**1023))'8.98846567431157954e+307
jlliagre
Saya akan mengingat ksh jika saya membutuhkan floating point atau nilai di stratosfer, floating point bisa sangat berguna. Tetapi pertanyaan ini hanya agar saya mengetahui batas-batas sistem saya, bukan karena saya harus melampaui batasnya. Saya akan melakukan sesuatu seperti mpy menyarankan, saya tidak memulainya karena saya tidak ingin risiko menyebabkan sistem crash.
Max Power

Jawaban:

22

Mungkin turun ke versi bash, OS, dan arsitektur CPU Anda. Mengapa Anda tidak mencobanya sendiri? Setel variabel menjadi (2 ^ 31) -1, lalu tambahkan, setel ke 2 ^ 32, lalu tambahkan, setel ke 2 ^ 64, lalu tambahkan, dll.

Di sini, saya hanya mencobanya sendiri pada Core i7 Mac saya yang menjalankan OS X "El Capitan" v10.11.3, dan sepertinya bash menggunakan integer 64-bit yang sudah ditandatangani.

$ uname -a
Darwin Spiff.local 15.3.0 Darwin Kernel Versi 15.3.0: Kamis 10 Des 18:40:58 PST 2015; root: xnu-3248.30.4 ~ 1 / RELEASE_X86_64 x86_64
$ bash --versi
bash --versi
GNU bash, versi 3.2.57 (1) -release (x86_64-apple-darwin15)
Hak Cipta (C) 2007 Free Software Foundation, Inc.
$
$ ((X = 2 ** 16)); gema $ X
65536 <- oke, setidaknya UInt16
$ ((X = 2 ** 32)); gema $ X
4294967296 <- oke, setidaknya UInt32
$ ((X = 2 ** 64)); gema $ X
0 <- oops, bukan UInt64
$ ((X = (2 ** 63) -1)); gema $ X
9223372036854775807 <- oke, setidaknya SInt64
$ ((X ++)); gema $ X
-9223372036854775808 <- meluap dan dibungkus negatif. Harus SInt64
Spiff
sumber
3

Saya mengatur lingkaran. while return status is 0 increment a variable with addition and print the variable to stdout Saya memulainya tepat di bawah 2 ^ 31, saya membiarkannya melewati 2 ^ 31 dan 2 ^ 32 tanpa masalah, menghentikannya, lalu menetapkan nilai awal menjadi di bawah 2 ^ 63. Hasilnya adalah itu berguling mulus dari 9.22e18 ke -9.22e18 dan terus meningkat secara positif. (menuju nol)

Hanya untuk memeriksa apakah saya while [ $? -eq 0 ]benar-benar menggunakan status keluar dari perintah dalam loop sementara, tidak menggunakan status keluar dari skrip sebelumnya atau keanehan, saya juga menjalankannya dengan perintah tambahan di dalam loop yang dirancang untuk membuat jalan keluar bukan nol status pada kenaikan tertentu.

Jadi itu ditandatangani, itu akan berguling bukannya berhenti pada nilai maksimal, dan ia melakukannya tanpa pesan kesalahan. Jadi dimungkinkan untuk berakhir dalam loop yang benar-benar tak terbatas. Itu tidak membatasi perangkat keras 64bit dan OS 64bit linux ke standar 16 atau 32bit lama.

Kekuatan penuh
sumber
2

bash gunakan integer 64-bit. Jadi jika Anda meningkatkan setelah variabel mencapai angka maksimalnya, variabel akan melimpah. Di bawah ini adalah tes saya dengan int unsigned dan integer yang ditandatangani.

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
sumber
2
tolong tambahkan beberapa teks yang menjelaskan bagaimana ini menjawab pertanyaan. Sepertinya Anda mencoba menunjukkan batas atas melalui kode - dapatkah Anda menjelaskan mengapa kode ini akan mencapai hasil yang diperlukan?
Sir Adelaide