Bash

找到 Bash 算術可以處理的最大數?

  • May 1, 2021

我怎樣才能讓我的腳本為自己確定最大的數字?

我查看了我的環境變數,發現這兩個看起來很有希望:

~# declare -p BASH_VERSINFO HOSTTYPE
declare -ar BASH_VERSINFO=([0]="5" [1]="0" [2]="11" [3]="1" [4]="release" [5]="x86_64-slackware-linux-gnu")
declare -- HOSTTYPE="x86_64"

…但是我真的可以相信解析這些,以便得出關於 Bash 算術中最大數字是多少的結論嗎?必須有更好的方法,以程式方式。有什麼建議麼?

Bash 算術使用有符號數。

所以快速的答案是:

((MAX=(1<<63)-1))

但是,既然您希望您的腳本不知道它正在執行的系統的位數,那麼讓我們繼續吧。

蠻力將是,繼續在循環中添加 1,直到你達到它將溢出到負數的地步。但這可能需要數年時間!:-) 一種更快、更優雅的方法是使用簡單的位移。

讓我們找到符號位,即,讓我們找到1最高有效位中的數字,以及所有其他位中的零,無論它們可能有多少。一旦我們有了那個數字,我們就簡單地減去1它,我們就會得到最大的有符號數。

# MIN -- the smallest signed number 0x8000...00  (it equals MAX+1)
# MAX -- the largest signed number  0x7Fff...FF  <-- what we are looking for

MIN=1; until (( (MIN<<=1) < 0 )) ;do :;done
((MAX=MIN-1))

echo $MAX

Result:
9223372036854775807

或者,這是一個單線,沒有循環。我們將一個數字的十六進製表示形式放在一個變數中,然後在傳遞給printf內置函式時通過變數擴展屏蔽符號位:

printf -v MAX %x -1 && printf -v MAX %d 0x${MAX/f/7}

echo $MAX

Result:
9223372036854775807

在與我的位數不同的機器上,結果將是不同的數字。

只是為了說明,在我的例子中:

printf "MAX %X  %d\nMIN %X %d\n" $MAX $MAX $MIN $MIN
MAX 7FFFFFFFFFFFFFFF  9223372036854775807
MIN 8000000000000000 -9223372036854775808

關於 MIN 的一點旁注:您可能希望限制自己使用((MIN=-MAX)),否則您偶爾會遇到一些算術運算的問題。

((MIN=-MAX)) ; printf "MIN %X %d\n" $MIN $MIN
MIN 8000000000000001 -9223372036854775807

引用自:https://unix.stackexchange.com/questions/643296