Printf
printf 是否有數字的“工程”符號格式?
假設我有這個數字:105000000,在這種形式下我無法輕易看出它有多大,所以
printf
在提示時我嘗試使用“科學”符號:% printf "%.3E" 105000000 1.050E+08
這更好,但我想使用“工程”符號,其中輸出格式為 10 3百萬、數十億、萬億等的冪。
例如,我想將其格式化為如下所示:
105000 => 105.0E+03 (105 thousand) 105000000 => 105.0E+06 (105 million) 105000000000 => 105.0E+09 (105 billion) ...
能
printf
做到嗎?
我不知道有任何
printf
實現。請注意,POSIX 甚至不保證printf '%E\n' 123
完全可以工作,因為對浮點格式的支持是可選的。通過多種
printf
實現,您可以使用%'f
在具有以下一種的語言環境中輸出千位分隔符:$ LC_NUMERIC=en_GB.UTF-8 printf "%'.0f\n" 105000000 105,000,000 $ LC_NUMERIC=fr_FR.UTF-8 printf "%'.0f\n" 105000000 105 000 000 $ LC_NUMERIC=da_DK.UTF-8 printf "%'.0f\n" 105000000 105.000.000 $ LC_NUMERIC=de_CH.UTF-8 printf "%'.0f\n" 105000000 105'000'000 $ LC_NUMERIC=ps_AF.UTF-8 printf "%'.0f\n" 105000000 105٬000٬000
使用
printf
內置的ksh93
,您還可以使用%#d
K/M/G… 後綴和%#i
Ki/Mi/Gi 後綴:$ printf '%#d\n' 105000000 $((2**22)) 105M 4.2M $ printf '%#i\n' 105000000 $((2**22)) 100Mi 4.0Mi
(但請注意,您無法更改精度,例如從
Ki
到的轉換Mi
為 1000 Ki,而不是 1024 Ki,如果您習慣了 GNU 格式(如 GNUls -lh
),這可能會令人驚訝。它也僅限於整數數字高達 2 63 -1 (8Ei - 1))。至於如何手動實現它,使用
zsh
:eng() { local n="${(j: :)argv}" exp zmodload zsh/mathfunc if ((n)) && ((exp = int(floor(log10(abs(n)) / 3)) * 3)); then printf '%.10ge%d\n' "n / 1e$exp" exp else printf '%.10g\n' "$n" fi }
進而:
$ eng 123 123 $ eng 12345 12.345e3 $ eng 0.000000123123 123.123e-9 $ eng 1. / -1234 -810.3727715e-6
請注意,
zsh
與許多其他語言一樣,涉及浮點數的操作是在浮點算術中完成的(使用您的處理器double
類型),而那些僅涉及整數的操作是在整數算術中完成的(使用您的處理器long
類型)。這有一些含義,例如:$ eng 1 / -1234 0 $ eng 1. / -1234 -810.3727715e-6
但是也:
$ eng 1 \*{2..28}. # factorial 28 304.8883446e27 $ eng 1 \*{2..28} -5.968160533e18 # 64bit signed integer overflow
(雖然這不是特定於該
eng
功能)或者作為使用 POSIX 的 POSIX shell 函式
bc
,因此允許任意精度:eng() ( IFS=" " scale=$1; shift bc -l << EOF | s = scale = $scale if (scale < 20) s = 20 n = $* if (n != 0) { scale = s a = n; if (a < 0) a = -a e = l(a) / l(10) / 3 + 10 ^ -15 if (e < 0) e -= 1 scale = 0 e = e / 1 * 3 scale = s if (scale <= -e) scale = 1 - e n = n / 10^e scale = $scale } n/1 if (e != 0) e EOF sed ' :1 /\\$/{ N;b1 } s/\\\n//g /\./s/0*$// s/\.$// $!N s/\n/e/' )
(在計算 n 值(如 0.001)的指數 log10(n) 時,偏移 1e-15 以抵消舍入誤差)
這裡將第一個參數作為scale:
$ eng 2 1/3 330e-3 $ eng 20 1/3 333.33333333333333333e-3
請注意,
bc
它本身並不理解工程符號,您必須編寫:$ eng 20 "1.123123 * 10^2000" 112.3123e1998