Bash
In bash
, die wahrscheinlich so gut wie es nur geht. Das nutzt eine eingebaute Shell. Wenn Sie das Ergebnis in einer Variablen benötigen, können Sie die Befehlssubstitution oder die bash
spezifische Funktion (die jetzt auch von unterstützt wird zsh
) verwenden:
printf -v int %.0f "$float"
Du könntest es tun:
float=1.23
int=${float%.*}
Aber das würde den Bruchteil entfernen, anstatt Ihnen die nächste Ganzzahl zu geben, und das würde nicht für Werte $float
wie 1.2e9
oder .12
zum Beispiel funktionieren .
Beachten Sie auch die möglichen Einschränkungen aufgrund der internen Darstellung von Floats:
$ printf '%.0f\n' 1e50
100000000000000007629769841091887003294964970946560
Sie erhalten eine Ganzzahl, aber es besteht die Möglichkeit, dass Sie diese Ganzzahl nirgendwo verwenden können.
Wie von @BinaryZebra bemerkt, wird es in verschiedenen printf
Implementierungen (bash, ksh93, yash, nicht GNU, zsh, dash) vom Gebietsschema (dem Dezimaltrennzeichen, das .
oder sein kann ,
) beeinflusst.
Wenn Ihre Gleitkommazahlen immer mit dem Punkt als Dezimaltrennzeichen angegeben werden und Sie möchten, dass sie printf
unabhängig vom Gebietsschema des Benutzers, der Ihr Skript aufruft, als solches behandelt werden , müssen Sie das Gebietsschema auf C festlegen:
LC_ALL=C printf '%.0f' "$float"
Mit yash
können Sie auch Folgendes tun:
printf '%.0f' "$(($float))"
(siehe unten).
POSIX
printf "%.0f\n" 1.1
ist nicht POSIX, da %f
es nicht von POSIX unterstützt werden muss.
POSIXly können Sie tun:
f2i() {
awk 'BEGIN{for (i=1; i<ARGC;i++)
printf "%.0f\n", ARGV[i]}' "$@"
}
Dieses ist vom Gebietsschema nicht betroffen (das Komma darf kein Dezimaltrennzeichen sein, awk
da es dort bereits ein Sonderzeichen in der Syntax ist ( print 1,2
dasselbe gilt für print 1, 2
die Übergabe von zwei Argumenten an print
).
zsh
In zsh
(das Gleitkomma-Arithmetik unterstützt (Dezimaltrennzeichen ist immer der Punkt)) haben Sie die rint()
mathematische Funktion, um die nächste Ganzzahl als Gleitkomma (wie in C
) und int()
eine Ganzzahl aus einem Gleitkomma (wie in awk
) anzugeben . Sie können also Folgendes tun:
$ zmodload zsh/mathfunc
$ i=$((int(rint(1.234e2))))
$ echo $i
123
Oder:
$ integer i=$((rint(5.678e2)))
$ echo $i
568
Beachten Sie jedoch, dass double
s zwar sehr große Zahlen darstellen kann, Ganzzahlen jedoch wesentlich eingeschränkter sind.
$ printf '%.0f\n' 1e123
999999999999999977709969731404129670057984297594921577392083322662491290889839886077866558841507631684757522070951350501376
$ echo $((int(1e123)))
-9223372036854775808
ksh93
ksh93 war die erste Bourne-ähnliche Shell, die Gleitkomma-Arithmetik unterstützt. ksh93 optimiert die Befehlsersetzung, indem keine Pipe verwendet oder gegabelt wird, wenn die Befehle nur eingebaute Befehle sind. Damit
i=$(printf '%.0f' "$f")
gabelt nicht. Oder noch besser:
i=${ printf '%.0f' "$f"; }
Das gibt auch nicht nach, macht aber auch nicht die ganze Mühe, eine gefälschte Subshell-Umgebung zu erstellen.
Sie können auch tun:
i=$((rint(f)))
Aber hüte dich vor:
$ echo "$((rint(1e18)))"
1000000000000000000
$ echo "$((rint(1e19)))"
1e+19
Sie könnten auch tun:
integer i=$((rint(f)))
Aber wie für zsh
:
$ integer i=1e18
$ echo "$i"
1000000000000000000
$ integer i=1e19
$ echo "$i"
-9223372036854775808
Beachten Sie, dass ksh93
Gleitkomma-Arithmetik die Dezimaltrennzeichen-Einstellung im Gebietsschema berücksichtigt (auch wenn ,
es sich ansonsten um einen mathematischen Operator handelt ( $((1,2))
wäre 6/5 in einem französisch / deutschen Gebietsschema und dasselbe wie $((1, 2))
2 in einem englischen Gebietsschema). .
yash
yash unterstützt auch Gleitpunktarithmetik aber keine mathematische Funktionen wie haben ksh93
/ zsh
‚s rint()
. Sie können eine Zahl in eine Ganzzahl umwandeln, indem Sie beispielsweise die Binärzahl oder den Operator verwenden (funktioniert auch in, zsh
aber nicht in ksh93
). Beachten Sie jedoch, dass der Dezimalteil abgeschnitten wird und nicht die nächste Ganzzahl angezeigt wird:
$ echo "$((0.237e2 | 0))"
23
$ echo "$((1e19))"
-9223372036854775808
yash
Berücksichtigt das Dezimaltrennzeichen des Gebietsschemas bei der Ausgabe, jedoch nicht die Gleitkomma-Literalkonstanten in den arithmetischen Ausdrücken, was zu Überraschungen führen kann:
$ LC_ALL=fr_FR.UTF-8 ./yash -c 'a=$((1e-2)); echo $(($a + 1))'
./yash: arithmetic: `,' is not a valid number or operator
Es ist in gewisser Weise gut, dass Sie Gleitkommakonstanten in Ihren Skripten verwenden können, die den Punkt verwenden, und sich nicht sorgen müssen, dass er in anderen Gebietsschemata nicht mehr funktioniert, aber dennoch in der Lage ist, die vom Benutzer ausgedrückten Zahlen so lange zu verarbeiten wie du dich erinnerst zu tun:
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