pesta
Dalam bash
, itu mungkin sama baiknya dengan yang didapat. Itu menggunakan builtin shell. Jika Anda membutuhkan hasil dalam variabel, Anda bisa menggunakan substitusi perintah, atau bash
spesifik (meskipun sekarang juga didukung oleh zsh
):
printf -v int %.0f "$float"
Anda bisa melakukannya:
float=1.23
int=${float%.*}
Tapi itu akan menghapus bagian pecahan alih-alih memberi Anda bilangan bulat terdekat dan itu tidak akan bekerja untuk nilai $float
suka 1.2e9
atau .12
misalnya.
Perhatikan juga batasan yang mungkin karena representasi internal dari pelampung:
$ printf '%.0f\n' 1e50
100000000000000007629769841091887003294964970946560
Anda memang mendapatkan integer, tetapi kemungkinan besar Anda tidak akan dapat menggunakan integer itu di mana pun.
Juga, seperti yang dicatat oleh @BinaryZebra, dalam beberapa printf
implementasi (bash, ksh93, yash, bukan GNU, zsh, dash), itu dipengaruhi oleh lokal (pemisah desimal yang dapat .
atau ,
).
Jadi, jika float Anda selalu dinyatakan dengan periode sebagai pemisah desimal dan Anda ingin diperlakukan seperti itu dengan printf
mengabaikan lokal pengguna yang menggunakan skrip Anda, Anda harus memperbaiki lokal ke C:
LC_ALL=C printf '%.0f' "$float"
Dengan yash
, Anda juga dapat melakukan:
printf '%.0f' "$(($float))"
(Lihat di bawah).
POSIX
printf "%.0f\n" 1.1
tidak POSIX karena %f
tidak perlu didukung oleh POSIX.
POSIXly, Anda dapat melakukan:
f2i() {
awk 'BEGIN{for (i=1; i<ARGC;i++)
printf "%.0f\n", ARGV[i]}' "$@"
}
Yang satu itu tidak terpengaruh oleh lokal (koma tidak bisa menjadi pemisah desimal awk
karena sudah karakter khusus dalam sintaksis di sana ( print 1,2
, sama print 1, 2
dengan meneruskan dua argumen ke print
)
zsh
Dalam zsh
(yang mendukung aritmatika titik mengambang (pemisah desimal selalu merupakan periode)), Anda memiliki rint()
fungsi matematika untuk memberi Anda bilangan bulat terdekat sebagai pelampung (seperti dalam C
) dan int()
untuk memberi Anda bilangan bulat dari pelampung (seperti dalam awk
). Jadi kamu bisa melakukan:
$ zmodload zsh/mathfunc
$ i=$((int(rint(1.234e2))))
$ echo $i
123
Atau:
$ integer i=$((rint(5.678e2)))
$ echo $i
568
Namun perhatikan bahwa sementara double
s dapat mewakili angka yang sangat besar, bilangan bulat jauh lebih terbatas.
$ printf '%.0f\n' 1e123
999999999999999977709969731404129670057984297594921577392083322662491290889839886077866558841507631684757522070951350501376
$ echo $((int(1e123)))
-9223372036854775808
ksh93
ksh93 adalah shell Bourne-like pertama yang mendukung aritmatika floating point. ksh93 mengoptimalkan substitusi perintah dengan tidak menggunakan pipa atau forking ketika perintah hanya dibangun dalam perintah. Begitu
i=$(printf '%.0f' "$f")
tidak bercabang. Atau lebih baik lagi:
i=${ printf '%.0f' "$f"; }
yang tidak bercabang dua juga tetapi tidak pergi semua kesulitan untuk menciptakan lingkungan subkulit palsu.
Anda juga dapat melakukan:
i=$((rint(f)))
Namun waspadalah terhadap:
$ echo "$((rint(1e18)))"
1000000000000000000
$ echo "$((rint(1e19)))"
1e+19
Anda juga bisa:
integer i=$((rint(f)))
Tapi seperti untuk zsh
:
$ integer i=1e18
$ echo "$i"
1000000000000000000
$ integer i=1e19
$ echo "$i"
-9223372036854775808
Berhati-hatilah bahwa ksh93
aritmatika titik apung menghormati pengaturan pemisah desimal di lokal (meskipun ,
sebaliknya operator matematika ( $((1,2))
akan menjadi 6/5 di lokal / Jerman ... lokal, dan sama dengan $((1, 2))
, yaitu 2 di lokal Inggris) .
yash
yash juga mendukung aritmatika floating point tetapi tidak memiliki fungsi matematika seperti ksh93
/ zsh
's rint()
. Anda dapat mengonversi angka menjadi bilangan bulat dengan menggunakan biner atau operator misalnya (juga berfungsi zsh
tetapi tidak di ksh93
). Perhatikan bahwa itu memotong bagian desimal, itu tidak memberi Anda bilangan bulat terdekat:
$ echo "$((0.237e2 | 0))"
23
$ echo "$((1e19))"
-9223372036854775808
yash
menghormati pemisah desimal lokal pada output, tetapi tidak untuk konstanta literal titik mengambang dalam ekspresi aritmatiknya, yang dapat menyebabkan kejutan:
$ LC_ALL=fr_FR.UTF-8 ./yash -c 'a=$((1e-2)); echo $(($a + 1))'
./yash: arithmetic: `,' is not a valid number or operator
Ini bagus karena Anda dapat menggunakan konstanta floating point dalam skrip Anda yang menggunakan periode dan tidak perlu khawatir bahwa itu akan berhenti bekerja di lokal lain, tetapi masih dapat menangani angka-angka seperti yang diungkapkan oleh pengguna selama seperti yang Anda ingat:
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