数値bashシェル変数の最大値は何ですか?


17

bashの数値変数を意図的に停止せずにインクリメントするとどうなるか、私は興味があります。数字はどれくらい大きくできますか?オーバーフローして負になり、永久に増加し続けますか?ある時点で壊れて停止するでしょうか?

私はx86_64 AMDプロセッサーを使用していますが、32ビットの回答も喜んで聞き、あなたが話しているものを指定してください。Fedora21 64bitを実行しています。

私は広くグーグルで検索しましたが、奇妙な理由でこの特定の情報を見つけていません。それはすべてのマニュアルなどの基本情報のようです。


3
どのようにスターターとして2のいくつかの力をプリントアウトについて:for i in {0..70}; do echo 2 to the power of $i = $((2**i)); done
MPY

1
大きな数値が必要な場合は、次のkshような整数演算ではなく、浮動小数点演算に切り替えることができますbashksh -c 'echo $((2**1023))'8.98846567431157954e+307
jlliagre

成層圏で浮動小数点または値が必要な場合は、kshを念頭に置きます。浮動小数点は非常に便利です。しかし、この質問は単にシステムの限界を知るためのものであり、その限界を超える必要があるからではありません。私はmpyが示唆するようなことをします。システムクラッシュを引き起こすリスクを望まないので、始めませんでした。
最大電力

回答:


22

これは、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バージョン15.3.0:2015年12月10日18:40:58 PST; ルート:xnu-3248.30.4〜1 / RELEASE_X86_64 x86_64
$ bash --version
bash-バージョン
GNU bash、バージョン3.2.57(1)-release(x86_64-apple-darwin15)
Copyright(C)2007 Free Software Foundation、Inc.
$
$((X = 2 ** 16)); エコー$ X
65536 <-OK、少なくともUInt16
$((X = 2 ** 32)); エコー$ X
4294967296 <-OK、少なくともUInt32
$((X = 2 ** 64)); エコー$ X
0 <-oops、UInt64ではない
$((X =(2 ** 63)-1)); エコー$ X
9223372036854775807 <-OK、少なくともSInt64
$((X ++)); エコー$ X
-9223372036854775808 <-オーバーフローし、ネガティブをラップしました。SInt64でなければなりません

3

ループを設定しました。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ビットの標準に限定するものではありません。


2

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
これが質問にどのように答えるかを説明するテキストを追加してください。コードで上限を実証しようとしているようです-このコードが必要な結果を達成する理由を説明できますか?
アデレード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.