如何將浮點數轉換為整數?
這是在bash中進行浮點到整數轉換的正確方法嗎?還有其他方法嗎?
flotToint() { printf "%.0f\n" "$@" }
重擊
在
bash
中,這可能是最好的。它使用內置的 shell。如果您需要變數中的結果,您可以使用命令替換或bash
特定的(儘管現在也支持zsh
):printf -v int %.0f "$float"
你可以這樣做:
float=1.23 int=${float%.*}
但這會刪除小數部分,而不是為您提供最接近的整數,並且不適用於
$float
like1.2e9
或.12
例如的值。還要注意由於浮點數的內部表示可能存在的限制:
$ printf '%.0f\n' 1e50 100000000000000007629769841091887003294964970946560
您確實得到了一個整數,但很可能您將無法在任何地方使用該整數。
此外,正如@BinaryZebra 所指出的,在幾個
printf
實現中(bash、ksh93、yash,而不是 GNU、zsh、dash),它受語言環境(可以是.
或的小數分隔符,
)的影響。因此,如果您的浮點數始終以句點作為小數分隔符表示,並且您希望無論呼叫您的腳本的使用者的語言環境如何,都將其視為這樣
printf
,您需要將語言環境修復為 C:LC_ALL=C printf '%.0f' "$float"
使用
yash
,您還可以執行以下操作:printf '%.0f' "$(($float))"
(見下文)。
POSIX
printf "%.0f\n" 1.1
不是 POSIX,因為 POSIX
%f
不需要支持。POSIXly,你可以這樣做:
f2i() { awk 'BEGIN{for (i=1; i<ARGC;i++) printf "%.0f\n", ARGV[i]}' "$@" }
那個不受語言環境的影響(逗號不能是小數點分隔符,
awk
因為它已經是那裡的語法中的特殊字元(print 1,2
,與print 1, 2
傳遞兩個參數相同zsh
在
zsh
(支持浮點運算(小數分隔符始終是句點))中,您可以使用rint()
數學函式為您提供最接近的整數作為浮點數(如 inC
)並int()
為您提供浮點數中的整數(如 inawk
)。所以你可以這樣做:$ zmodload zsh/mathfunc $ i=$((int(rint(1.234e2)))) $ echo $i 123
或者:
$ integer i=$((rint(5.678e2))) $ echo $i 568
但是請注意,雖然
double
s 可以表示非常大的數字,但整數的限制要大得多。$ printf '%.0f\n' 1e123 999999999999999977709969731404129670057984297594921577392083322662491290889839886077866558841507631684757522070951350501376 $ echo $((int(1e123))) -9223372036854775808
ksh93
ksh93 是第一個支持浮點運算的類似 Bourne 的 shell。當命令只是內置命令時,ksh93 通過不使用管道或分叉來優化命令替換。所以
i=$(printf '%.0f' "$f")
不分叉。甚至更好:
i=${ printf '%.0f' "$f"; }
它也不會分叉,但也不會為創建假的 subshell 環境而煩惱。
你也可以這樣做:
i=$((rint(f)))
但要注意:
$ echo "$((rint(1e18)))" 1000000000000000000 $ echo "$((rint(1e19)))" 1e+19
你也可以這樣做:
integer i=$((rint(f)))
但喜歡
zsh
:$ integer i=1e18 $ echo "$i" 1000000000000000000 $ integer i=1e19 $ echo "$i" -9223372036854775808
請注意,
ksh93
浮點算術尊重語言環境中的小數分隔符設置(即使,
是數學運算符($((1,2))
在法語/德語…語言環境中為 6/5,與 相同$((1, 2))
,即在英語語言環境中為 2) .雅什
yash 還支持浮點運算,但沒有
ksh93
/zsh
之類的數學函式rint()
。例如,您可以使用二進製或運算符將數字轉換為整數(也適用於zsh
但不適用於ksh93
)。但是請注意,它會截斷小數部分,它不會為您提供最接近的整數:$ echo "$((0.237e2 | 0))" 23 $ echo "$((1e19 | 0))" -9223372036854775808
yash
在輸出時尊重語言環境的小數分隔符,但不尊重其算術表達式中的浮點文字常量,這可能會導致意外:$ LC_ALL=fr_FR.UTF-8 ./yash -c 'a=$((1e-2)); echo $(($a + 1))' ./yash: arithmetic: `,' is not a valid number or operator
這在某種程度上很好,因為您可以在使用句點的腳本中使用浮點常量,而不必擔心它會在其他語言環境中停止工作,但仍然能夠處理使用者表達的數字正如你記得做的那樣:
var=$((10.3)) # and not var=10.3 ... "$((a + 0.1))" # and not "$(($a + 0.1))". printf '%.0f\n' "$((10.3))" # and not printf '%.0f\n' 10.3