darbe
In bash
, muhtemelen alabileceği kadar iyi. Bu bir kabuk yerleşik kullanır. Eğer bir değişkenin sonucu gerekiyorsa, komut ikame veya kullanabilir bash
spesifik (gerçi şimdi de desteklediği zsh
):
printf -v int %.0f "$float"
Yapabilirsin:
float=1.23
int=${float%.*}
Fakat bu size en yakın tamsayıyı vermek yerine kesirli kısmı ortadan kaldıracak ve bu $float
gibi 1.2e9
ya da .12
örneğin değerleri için işe yaramayacaktı .
Ayrıca, şamandıraların dahili gösterimi nedeniyle olası sınırlamaları not edin:
$ printf '%.0f\n' 1e50
100000000000000007629769841091887003294964970946560
Bir tamsayı elde edersiniz, ancak bu tamsayı hiçbir yerde kullanamayacağınız ihtimali vardır.
Ayrıca, @BinaryZebra tarafından belirtildiği gibi, çeşitli printf
uygulamalarda (bash, ksh93, yash, GNU, zsh, dash değil), yerel ayardan etkilenebilir (ondalık ayırıcı olabilir .
veya olabilir ,
).
Bu nedenle, kayan noktalarınız her zaman ondalık ayırıcı olarak dönemle ifade edilirse ve printf
komut dosyasını çağıran kullanıcının yerel ayarına bakılmaksızın bunun gibi değerlendirilmesini istiyorsanız, yerel ayarı C'ye sabitlemeniz gerekir:
LC_ALL=C printf '%.0f' "$float"
İle yash
şunları da yapabilirsiniz:
printf '%.0f' "$(($float))"
(aşağıya bakınız).
POSIX
printf "%.0f\n" 1.1
POSIX %f
tarafından desteklenmesi gerekmediğinden POSIX değildir.
POSIXly şunları yapabilirsiniz:
f2i() {
awk 'BEGIN{for (i=1; i<ARGC;i++)
printf "%.0f\n", ARGV[i]}' "$@"
}
Bir yerel ayar etkilenmez O (virgül bir ondalık ayırıcı olamaz awk
zaten sözdiziminde özel bir karakter beri orada ( print 1,2
aynı print 1, 2
üzere iki argüman geçmek print
)
zsh
In zsh
(ondalık ayırıcı daima dönem) olan kayar nokta aritmetik destekler (), sahip rint()
bir float olarak (in sever yakın tamsayı vermek için matematik fonksiyonu C
) ve int()
(filmindeki gibi bir şamandıra gelen size bir tamsayı vermek awk
). Yani yapabilirsin:
$ zmodload zsh/mathfunc
$ i=$((int(rint(1.234e2))))
$ echo $i
123
Veya:
$ integer i=$((rint(5.678e2)))
$ echo $i
568
Bununla birlikte, double
s çok büyük sayıları temsil etse de, tam sayılar çok daha sınırlıdır.
$ printf '%.0f\n' 1e123
999999999999999977709969731404129670057984297594921577392083322662491290889839886077866558841507631684757522070951350501376
$ echo $((int(1e123)))
-9223372036854775808
ksh93
ksh93, kayan nokta aritmetiğini destekleyen ilk Bourne benzeri kabuktur. ksh93 komutları yalnızca yerleşik komutlar olduğunda, bir boru kullanmadan veya çatal kullanarak komut değiştirmeyi optimize eder. Yani
i=$(printf '%.0f' "$f")
çatal değil. Veya daha da iyisi:
i=${ printf '%.0f' "$f"; }
Bu da ya çatal değil aynı zamanda sahte bir deniz kabuğu ortamı yaratma zorluğuna da yol açmaz.
Ayrıca şunları da yapabilirsiniz:
i=$((rint(f)))
Ancak dikkat:
$ echo "$((rint(1e18)))"
1000000000000000000
$ echo "$((rint(1e19)))"
1e+19
Ayrıca şunları da yapabilirsiniz:
integer i=$((rint(f)))
Ancak bunun için zsh
:
$ integer i=1e18
$ echo "$i"
1000000000000000000
$ integer i=1e19
$ echo "$i"
-9223372036854775808
ksh93
Kayan nokta aritmetiğinin yerel ayardaki ondalık ayırıcı ayarını onurlandırdığına dikkat edin ( ,
aksi halde bir matematik işleci olsa da ( $((1,2))
Fransızca / Almanca ... yerel ayarında 6/5 olur ve aynı $((1, 2))
, İngilizce ayarında 2 olur) .
yash
yash, kayan nokta aritmetiğini de destekler, ancak ksh93
/ zsh
's gibi matematik işlevlerine sahip değildir rint()
. Örneğin bir ikiliyi veya işlecini kullanarak bir sayıyı tamsayıya dönüştürebilirsiniz (aynı zamanda içinde çalışır zsh
ancak içinde değildir ksh93
). Ancak ondalık parçayı kısalttığına, size en yakın tamsayıya sahip olmadığını unutmayın:
$ echo "$((0.237e2 | 0))"
23
$ echo "$((1e19))"
-9223372036854775808
yash
yerelin çıktıdaki ondalık ayırıcısını onurlandırır, ancak aritmetik ifadelerinde kayan nokta değişmez sabitleri için değil, sürprizlere neden olabilir:
$ LC_ALL=fr_FR.UTF-8 ./yash -c 'a=$((1e-2)); echo $(($a + 1))'
./yash: arithmetic: `,' is not a valid number or operator
Komut dosyalarınızda, süreyi kullanan kayan nokta sabitlerini kullanabilmeniz ve başka yerlerde çalışmayı bırakacağından endişe etmenize gerek kalmaması, ancak yine de kullanıcı tarafından belirtilen sayılarla başa çıkabilmeniz için iyi bir yöntemdir. Yapmayı hatırladığın gibi:
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