Apakah ini cara yang tepat untuk melakukan konversi float ke integer di bash? Apakah ada metode lain?
flotToint() {
printf "%.0f\n" "$@"
}
bash
floating-point
Rahul Patil
sumber
sumber
%.0f
akan dibulatkan ke atas atau ke bawah. Apakah itu yang kamu inginkan? Anda dapat menggunakanprintf "%d\n" "$@" 2>/dev/null
untuk memotong fraksi.Jawaban:
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, ataubash
spesifik (meskipun sekarang juga didukung olehzsh
):Anda bisa melakukannya:
Tapi itu akan menghapus bagian pecahan alih-alih memberi Anda bilangan bulat terdekat dan itu tidak akan bekerja untuk nilai
$float
suka1.2e9
atau.12
misalnya.Perhatikan juga batasan yang mungkin karena representasi internal dari pelampung:
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:Dengan
yash
, Anda juga dapat melakukan:(Lihat di bawah).
POSIX
tidak POSIX karena
%f
tidak perlu didukung oleh POSIX.POSIXly, Anda dapat melakukan:
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
, samaprint 1, 2
dengan meneruskan dua argumen keprint
)zsh
Dalam
zsh
(yang mendukung aritmatika titik mengambang (pemisah desimal selalu merupakan periode)), Anda memilikirint()
fungsi matematika untuk memberi Anda bilangan bulat terdekat sebagai pelampung (seperti dalamC
) danint()
untuk memberi Anda bilangan bulat dari pelampung (seperti dalamawk
). Jadi kamu bisa melakukan:Atau:
Namun perhatikan bahwa sementara
double
s dapat mewakili angka yang sangat besar, bilangan bulat jauh lebih terbatas.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
tidak bercabang. Atau lebih baik lagi:
yang tidak bercabang dua juga tetapi tidak pergi semua kesulitan untuk menciptakan lingkungan subkulit palsu.
Anda juga dapat melakukan:
Namun waspadalah terhadap:
Anda juga bisa:
Tapi seperti untuk
zsh
: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
'srint()
. Anda dapat mengonversi angka menjadi bilangan bulat dengan menggunakan biner atau operator misalnya (juga berfungsizsh
tetapi tidak diksh93
). Perhatikan bahwa itu memotong bagian desimal, itu tidak memberi Anda bilangan bulat terdekat:yash
menghormati pemisah desimal lokal pada output, tetapi tidak untuk konstanta literal titik mengambang dalam ekspresi aritmatiknya, yang dapat menyebabkan kejutan: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:
sumber
int=${float%.*}
bekerja sangat baik di skrip bash saya (versi 3.2.57 (1) -release) di Mac (versi 10.13.4 (17E199)).,
radix desimal. Lihat bagian tentangLC_ALL=C
bc
- Bahasa kalkulator presisi arbitrerint (float) akan terlihat seperti:
Untuk lebih baik gunakan ini:
Contoh:
sumber
float=-2; echo "($float+0.5)/1" | bc
memberi-1
.Jawaban sebelumnya yang diajukan hampir benar: "Anda bisa melakukan:
Tetapi itu akan menghapus bagian pecahan alih-alih memberi Anda bilangan bulat terdekat dan itu tidak akan bekerja untuk nilai $ float seperti 1.2e9 atau .12 misalnya .... "
Gunakan saja
${float%%.*}
.sumber
Yang sangat sederhana adalah hacky
Output sampel
sumber
sed
, tetapicut
solusinya lebih sederhana. Saya lebih sukased
ataucut
karena mereka IMHO lebih tersedia pada target tertanam daripadaawk
(yang masih cukup umum melaluibusybox
daripadabc
).Terkait:
Melengkapi @ Stéphane Chazelas
awk
jawab:sumber
printf
, atau jika ada alasan lain untuk lebih memilih awk daripada yang builtinprintf
.