web-dev-qa-db-ja.com

数値bashシェル変数の最大値はいくつですか?

Bashの数値変数が意図的に停止せずにインクリメントされるとどうなるかについて知りたいです。数はどのくらい大きくなりますか?それはオーバーフローしてネガティブになり、永久に増加し続けますか?それは壊れて、どこかの地点で滑って停止しますか?

私はx86_64 AMDプロセッサを使用していますが、32ビットの回答も聞かせていただければ幸いです。 Fedora21 64ビットを実行しています。

私はずっとググってみましたが、奇妙な理由でこの特定の情報を見つけられませんでした。それはすべてのマニュアルなどの基本的な情報のようです。

18
Max Power

これは、bashのバージョン、OS、およびCPUアーキテクチャに起因する場合があります。自分で試してみませんか?変数を(2 ^ 31)-1に設定し、次にインクリメントし、2 ^ 32に設定し、次にインクリメントし、2 ^ 64に設定してからインクリメントする、などです.

ここでは、OS X "El Capitan" v10.11.3を実行しているCore i7 Macで試してみましたが、bashが符号付き64ビット整数を使用しているようです。

 $ uname -a 
 Darwin Spiff.local 15.3.0 Darwin Kernel Version 15.3.0:Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4〜1/RELEASE_X86_64 x86_64 
 $ bash --version 
 bash --version 
 GNU bash、バージョン3.2.57(1)-release(x86_64 -Apple-darwin15)
 Copyright(C)2007 Free Software Foundation、Inc。
 $ 
 $((X = 2 ** 16)); echo $ X 
 65536 <-わかりました、少なくともUInt16 
 $((X = 2 ** 32)); echo $ X 
 4294967296 <-わかりました、少なくともUInt32 
 $((X = 2 ** 64)); echo $ X 
 0 <-oops、not UInt64 
 $((X =(2 ** 63)-1)); echo $ X 
 9223372036854775807 <-わかりました、少なくともSInt64 
 $((X ++)); echo $ X 
-9223372036854775808 <-オーバーフローし、ネガティブラップされました。 SInt64 
である必要があります
23
Spiff

ループを設定しました。 while return status is 0 increment a variable with addition and print the variable to stdout 2 ^ 31未満で開始し、2 ^ 31と2 ^ 32の両方を問題なく通過させ、停止して、初期値を2 ^ 63未満に設定しました。その結果、9.22e18から-9.22e18にシームレスにロールオーバーし、確実に増加し続けました。 (ゼロに向かって)

私のwhile [ $? -eq 0 ]は、実際には、whileループ内のコマンドの終了ステータスを使用していましたが、前のスクリプトの終了ステータスや奇妙なものを使用していませんでした。特に、ゼロ以外の終了ステータスを作成するように設計されたループ内の追加コマンドで実行しました。増分。

そのため、署名され、最大値で停止するのではなくロールオーバーし、エラーメッセージなしでロールオーバーします。そのため、本当に無限ループになる可能性があります。 64ビットのハードウェアと64ビットのLinux OSを古い16または32ビット規格に制限するものではありません。

3
Max Power

bash 64ビット整数を使用します。したがって、変数がその最大数に達した後に増加すると、変数はオーバーフローします。以下は、符号なし整数と符号付き整数を使用したテストです。

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
PT Huynh