Sayısal bash kabuk değişkeninin maksimum değeri nedir?


17

Bash'teki sayısal bir değişken bilerek durdurulmadan artırıldığında ne olacağını merak ediyorum. Sayı ne kadar büyük olabilir? Taşacak ve negatif olacak ve sadece sonsuza kadar artmaya devam edecek mi? Bir noktada kırılacak ve duracak mı?

Bir x86_64 AMD işlemci kullanıyorum, ancak 32 bit cevapları da duymaktan memnuniyet duyarım, sadece neden bahsettiğinizi belirtin. Fedora21 64bit kullanıyorum.

Çok geniş çapta googledim ama bu garip bir nedenden ötürü bu özel çöpü bulamadım. Görünüşe göre tüm el kitaplarında temel bir bilgi parçası gibi görünecektir.


3
Başlangıç ​​olarak 2'nin bazı güçlerini basmaya ne dersiniz:for i in {0..70}; do echo 2 to the power of $i = $((2**i)); done
mpy

1
Eğer büyük sayılar istiyorsanız ksh, kayan nokta aritmetiği yerine geçebilirsiniz , tamsayı gibi değil bash: ksh -c 'echo $((2**1023))'8.98846567431157954e+307
jlliagre

Stratosferde kayan nokta veya değerlere ihtiyacım olursa ksh'ı aklımda tutacağım, kayan nokta oldukça yararlı olabilir. Ama bu soru basitçe öyle ki sistemimin sınırlarını biliyorum, çünkü sınırlarını aşmam gerektiğinden değil. Mpy'nin önerdiği gibi bir şey yapacağım, başlamamıştım çünkü bir sistem çökmesine neden olma riski istemiyordum.
Maksimum Güç

Yanıtlar:


22

Bu, bash sürümünüze, işletim sisteminize ve CPU mimarinize gelebilir. Neden kendin denemiyorsun? Bir değişkeni (2 ^ 31) -1 olarak ayarlayın, ardından artırın, 2 ^ 32 olarak ayarlayın, sonra artırın, 2 ^ 64 olarak ayarlayın, sonra artırın, vb.

Burada, kendimi OS X "El Capitan" v10.11.3 çalıştıran Core i7 Mac'imde denedim ve bash imzalı 64 bit tam sayıları kullanıyor gibi görünüyor.

$ uname -a
Darwin Spiff.local 15.3.0 Darwin Çekirdeği Sürüm 15.3.0: Per 10 Aralık 18:40:58 PST 2015; kök: xnu-3248.30.4 ~ 1 / RELEASE_X86_64 x86_64
$ bash - sürüm
bash - sürüm
GNU bash, sürüm 3.2.57 (1) -çalışma (x86_64-apple-darwin15)
Telif Hakkı (C) 2007 Free Software Foundation, Inc.
$
$ ((X = 2 ** 16)); echo $ X
65536 <- tamam, en azından UInt16
$ ((X = 2 ** 32)); echo $ X
4294967296 <- tamam, en azından UInt32
$ ((X = 2 ** 64)); echo $ X
0 <- ayy, UInt64 değil
$ ((X = (2 ** 63) -1)); echo $ X
9223372036854775807 <- tamam, en azından SInt64
$ ((X ++)); echo $ X
-9223372036854775808 <- taşmış ve negatif sarılmış. SInt64 olmalı

3

Bir döngü kurdum. while return status is 0 increment a variable with addition and print the variable to stdout Hemen 2 ^ 31 altında başladım, hem 2 ^ 31 hem de 2 ^ 32'yi sorunsuz geçmesine izin verdim, durdurdum, sonra başlangıç ​​değerini 2 ^ 63'ün altına ayarladım. Sonuç olarak, 9.22e18'den -9.22e18'e sorunsuz bir şekilde yuvarlandı ve pozitif olarak artmaya devam etti. (sıfıra doğru)

Sadece while [ $? -eq 0 ]önceki komut dosyasının çıkış durumunu veya bazı tuhaflıkları kullanmadan, while döngüsünde komutların çıkış durumunu kullandığımı kontrol etmek için, sıfır olmayan bir çıkış oluşturmak için tasarlanmış döngü içinde ekstra bir komutla da çalıştırdım belirli artışlarla durumu.

Bu yüzden imzalanmış, maksimum değerde durmak yerine devrilecek ve herhangi bir hata mesajı olmadan bunu yapacak. Böylece gerçekten sonsuz bir döngü elde etmek mümkündür. 64bit donanım ve 64bit linux işletim sistemini eski bir 16 veya 32bit standartla sınırlamaz.


2

bash 64 bit tam sayı kullanır. Dolayısıyla, değişken maksimum sayısına ulaştıktan sonra artarsanız değişken taşar. Aşağıda imzasız int ve imzalı tamsayı olan testim var.

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
lütfen bunun soruyu nasıl yanıtladığını açıklayan bir metin ekleyin. Üst sınırları kodla göstermeye çalıştığınız anlaşılıyor - bu kodun neden gerekli sonucu elde edeceğini açıklayabilir misiniz?
Sir Adelaide
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.