In einfachen Fällen können Sie sicher int()
verwenden, die gegen Null kürzt:
awk 'BEGIN { print int(3/2) }' # prints 1
gawk 'BEGIN { print int(-3/2) }' # prints -1; not guaranteed in POSIX awk
Beachten Sie, dass immer awk verwendet doppelter Genauigkeit Gleitkommazahlen und Fließkomma-Arithmetik , obwohl. Die einzige Möglichkeit, Ganzzahlen und Ganzzahlarithmetik zu erhalten, besteht darin, externe Werkzeuge zu verwenden, z. der Standard-expr
Dienstprogramm:
awk 'BEGIN { "expr 3/2" | getline result; print result; }' # prints 1
Das ist wirklich awk Station, lange, langsame, ... aber sicher und tragbar.
In POSIX awk wird Trunkierung auf Null für positive Argumente nur dann gewährleistet: int (x) - das Argument auf eine ganze Zahl gekürzt zurückzukehren. Die Abschneidung soll gegen 0 gehen, wenn x> 0 ist.GNU awk (gawk) verwendet Trunkierung in Richtung Null auch für negative Zahlen: int (x) - Gibt die nächste Ganzzahl an x zurück, die sich zwischen x und null befindet und gegen Null abgeschnitten ist. Zum Beispiel ist int (3) 3, int (3,9) ist 3, int (-3,9) ist -3, und int (-3) ist ebenfalls -3.Numerische Ausdrücke werden in POSIX als Expressions in awk mit doppelter Genauigkeit angegeben.
Alle Arithmetik wird die Semantik von Gleitkomma-Arithmetik wie spezifiziert durch die ISO-C-Standard (siehe Concepts Derived from the ISO C Standard) folgen. - POSIX awk: Arithmetic functions
Wenn Sie Schwimmer verwenden, sollten Sie über ihre Macken kennen und bereit sein, sie zu entdecken und damit verbundene Fehler zu vermeiden. Mehrere beängstigend Beispiele:
nicht darstellbare Zahlen:
awk 'BEGIN { x = 0.875; y = 0.425; printf("%0.17g, %0.17g\n", x, y) }'
# prints 0.875, 0.42499999999999999
Round-off errors Akkumulation:
awk 'BEGIN{s=0; for(i=1;i<=100000;i++)s+=0.3; printf("%.10f, %d\n",s,int(s))}'
# prints 29999.9999999506, 29999
Rundungsfehler ruinieren Vergleiche:
awk 'BEGIN { print (0.1 + 12.2 == 12.3) }' # prints 0
Precision nimmt mit Größe, was zu Endlosschleifen:
awk 'BEGIN { for (i=10^16; i<10^16+5; i++) printf("%d\n", i) }'
# prints 10000000000000000 infinitely many times
Lesen Sie mehr darüber, wie schwimmt Arbeit:
Stack-Überlauf-Tags floating-point wiki
Wikipedia-Artikel Floating point
GNU awk arbitrary precision arithmetic - enthält sowohl Informationen über die konkrete Umsetzung und Allgemeinwissen
Ich denke, eine Möglichkeit, die schwimmenden Fehler zu überwinden (für relativ kleine Zahlen) wäre "int (3/2 + 0,25)". – user000001
@ user000001 Das Hinzufügen einer Konstante löst das Problem nicht, es fügt tatsächlich ein neues hinzu. 'awk 'BEGIN {print int (7/8), int (7/8 + 0,25)}' erzeugt '0 1'. – Palec
Ja, es müsste kleiner sein als '1/(d/2)', wobei "d" der Nenner ist. Solange dieser Wert größer als der Floating-Fehler ist, sollte es funktionieren. – user000001