openSUSE 12.2 - mein awk spinnt
Hallo zusammen, Ich hatte mir (für ein anderes Problem) ein kleines awk-Script geschrieben, das mir aus einer grossen Ausgangsdatei durch zusammenfassen und addieren eine kleinere Datei bauen sollte. Die Prüfung ergab aber immer wieder Fehler; ich konnte den Fehler exemplarisch eingrenzen: folgendes awk-Skript: awk 'BEGIN {x=8.12*100} END {printf "snum=%d, stxt=%s, x, x} <file> liefert IMMER: snum=811, stxt=812 Was'n das? Kann awk nicht mal einfachste Rechenaufgaben erledigen? (Ein äquivalentes Konstrukt in z.B. perl funktioniert einwandfrei) Kann mir das irgendjemand schlüssig erklären? (Der Fehler ist NICHT suse spezifisch; hier passiert das auch unter z.B. Solaris10) Verwirrt und ratlos. Andreas -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
On Wednesday 29 February 2012 12:19:10 Kyek, Andreas, VF-DE wrote:
Hallo zusammen,
Ich hatte mir (für ein anderes Problem) ein kleines awk-Script geschrieben, das mir aus einer grossen Ausgangsdatei durch zusammenfassen und addieren eine kleinere Datei bauen sollte. Die Prüfung ergab aber immer wieder Fehler; ich konnte den Fehler exemplarisch eingrenzen:
folgendes awk-Skript:
awk 'BEGIN {x=8.12*100} END {printf "snum=%d, stxt=%s, x, x} <file>
liefert IMMER: snum=811, stxt=812
Was passiert denn wenn Du beides Mal %s bzw %d als Formatqualifier verwendest? Liebe Grüße Alexander -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Kyek, Andreas, VF-DE [29.02.2012 12:19]:
Hallo zusammen,
Ich hatte mir (für ein anderes Problem) ein kleines awk-Script geschrieben, das mir aus einer grossen Ausgangsdatei durch zusammenfassen und addieren eine kleinere Datei bauen sollte. Die Prüfung ergab aber immer wieder Fehler; ich konnte den Fehler exemplarisch eingrenzen:
folgendes awk-Skript:
awk 'BEGIN {x=8.12*100} END {printf "snum=%d, stxt=%s, x, x} <file>
liefert IMMER: snum=811, stxt=812
Was'n das? Kann awk nicht mal einfachste Rechenaufgaben erledigen? (Ein äquivalentes Konstrukt in z.B. perl funktioniert einwandfrei)
Kann mir das irgendjemand schlüssig erklären?
(Der Fehler ist NICHT suse spezifisch; hier passiert das auch unter z.B. Solaris10)
Verwirrt und ratlos.
Andreas
Einwandfrei funktioniert: awk 'BEGIN {x=8.12*100} END {printf "snum=%.0f, stxt=%s\n", x, x}' \ < /dev/null Vermutlich ein Rundungsproblem beim Typecasting ;-) HTH Werner -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk9OC64ACgkQk33Krq8b42P+mwCdGqciR2+9sWQRXAKdGOmTaPMd UEcAnjHNxNszS43ltOWMgSEpdThNw53o =Zfyy -----END PGP SIGNATURE----- -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
Werner Flamme wrote:
Kyek, Andreas, VF-DE [29.02.2012 12:19]:
Hallo zusammen,
Ich hatte mir (für ein anderes Problem) ein kleines awk-Script geschrieben, das mir aus einer grossen Ausgangsdatei durch zusammenfassen und addieren eine kleinere Datei bauen sollte. Die Prüfung ergab aber immer wieder Fehler; ich konnte den Fehler exemplarisch eingrenzen:
folgendes awk-Skript:
awk 'BEGIN {x=8.12*100} END {printf "snum=%d, stxt=%s, x, x} <file>
liefert IMMER: snum=811, stxt=812
Was'n das? Kann awk nicht mal einfachste Rechenaufgaben erledigen? (Ein äquivalentes Konstrukt in z.B. perl funktioniert einwandfrei)
Kann mir das irgendjemand schlüssig erklären?
(Der Fehler ist NICHT suse spezifisch; hier passiert das auch unter z.B. Solaris10)
Verwirrt und ratlos.
Andreas
Einwandfrei funktioniert:
awk 'BEGIN {x=8.12*100} END {printf "snum=%.0f, stxt=%s\n", x, x}' \ < /dev/null
Vermutlich ein Rundungsproblem beim Typecasting ;-)
Ich antworte dir mal stellvertretend: - ich weiss, wie ich es richtig ausgegeben bekomme; das ist nicht der Punkt - ich verstehe NICHT, wie eine einfache Ganzzahl (die durch eine Rechnung ermittelt wird) bei einer formtierten Ausgabe als Ganzzahl (nichts anderes ist %d ja) zu einem falschen Ergebnis führen kann. Da muss nach meinem Verständnis nix gerundet werden; und die Zahl ist auch nicht so gross, das die Beschränkung der Zahlen auf x Ziffern irgendeine Rolle spielen könnte. So etwas konnte schon mein uralter 6502/Z80 Prozessor besser! Ich erinnnere mich das ich auf dieses "phänomen" schon ein paar mal bei meinen Skripten gestossen bin und (nicht zuletzt deswegen) awk immer seltener verwende. Andreas -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Kyek, Andreas, VF-DE [29.02.2012 12:33]:
Werner Flamme wrote:
Kyek, Andreas, VF-DE [29.02.2012 12:19]:
Hallo zusammen,
Ich hatte mir (für ein anderes Problem) ein kleines awk-Script geschrieben, das mir aus einer grossen Ausgangsdatei durch zusammenfassen und addieren eine kleinere Datei bauen sollte. Die Prüfung ergab aber immer wieder Fehler; ich konnte den Fehler exemplarisch eingrenzen:
folgendes awk-Skript:
awk 'BEGIN {x=8.12*100} END {printf "snum=%d, stxt=%s, x, x} <file>
liefert IMMER: snum=811, stxt=812
Was'n das? Kann awk nicht mal einfachste Rechenaufgaben erledigen? (Ein äquivalentes Konstrukt in z.B. perl funktioniert einwandfrei)
Kann mir das irgendjemand schlüssig erklären?
(Der Fehler ist NICHT suse spezifisch; hier passiert das auch unter z.B. Solaris10)
Verwirrt und ratlos.
Andreas
Einwandfrei funktioniert:
awk 'BEGIN {x=8.12*100} END {printf "snum=%.0f, stxt=%s\n", x, x}' \ < /dev/null
Vermutlich ein Rundungsproblem beim Typecasting ;-)
Ich antworte dir mal stellvertretend:
- ich weiss, wie ich es richtig ausgegeben bekomme; das ist nicht der Punkt
Das hättest Du auch ins OP schreiben können, dann hätte ich gar nicht erst nachgesehen. Und wenn Du weißt, wie es richtig geht, warum machst Du es dann nicht richtig?
- ich verstehe NICHT, wie eine einfache Ganzzahl (die durch eine Rechnung ermittelt wird) bei einer formtierten Ausgabe als Ganzzahl (nichts anderes ist %d ja) zu einem falschen Ergebnis führen kann. Da muss nach meinem Verständnis nix gerundet werden; und die Zahl ist auch nicht so gross, das die Beschränkung der Zahlen auf x Ziffern irgendeine Rolle spielen könnte. So etwas konnte schon mein uralter 6502/Z80 Prozessor besser!
Ich erinnnere mich das ich auf dieses "phänomen" schon ein paar mal bei meinen Skripten gestossen bin und (nicht zuletzt deswegen) awk immer seltener verwende.
Andreas
Um mal die man-Page von awk zu zitieren: AWK variables are dynamic; they come into existence when they are first used. Their values are either floating-point numbers or strings, or both, depending upon how they are used. Von ganzzahligen Variablen sehe ich da nichts. Und wenn Du eine Zahl 8.12 mit 100 multiplizierst, ist das vielleicht für Dein Kopfrechnen 812. Für einen Computer noch lange nicht. Der erfasst das intern vielleicht als 811.999999999. Ein simples "%d" gibt den ganzzahligen Anteil aus -> 811. Ein %.0f gibt die gerundete ganze Zahl aus -> 812. AWK ist eine Programmiersprache. Beachtet man ihre Eigenheiten nicht, funktioniert sie nicht wie gewünscht. Das ist aber eigentlich bei allen Programmiersprachen so. Gruß Werner -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk9ODyAACgkQk33Krq8b42N40gCeMTJoCvVpNVLExKwL/xGda3+y LPUAn2seKrekG9NYgPcM07PatAn005jQ =XBg2 -----END PGP SIGNATURE----- -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
Hallo, Am Wed, 29 Feb 2012, Werner Flamme schrieb:
Kyek, Andreas, VF-DE [29.02.2012 12:33]:
Werner Flamme wrote:
Kyek, Andreas, VF-DE [29.02.2012 12:19]:
folgendes awk-Skript:
awk 'BEGIN {x=8.12*100} END {printf "snum=%d, stxt=%s, x, x} <file>
liefert IMMER: snum=811, stxt=812 [..] Um mal die man-Page von awk zu zitieren:
AWK variables are dynamic; they come into existence when they are first used. Their values are either floating-point numbers or strings, or both, depending upon how they are used.
Von ganzzahligen Variablen sehe ich da nichts.
Und wenn Du eine Zahl 8.12 mit 100 multiplizierst, ist das vielleicht für Dein Kopfrechnen 812. Für einen Computer noch lange nicht. Der erfasst das intern vielleicht als 811.999999999. Ein simples "%d" gibt den ganzzahligen Anteil aus -> 811. Ein %.0f gibt die gerundete ganze Zahl aus -> 812.
Fast. Schauen wir doch mal, was AWK da binär rechnet: $ echo 'obase=2; 8.12; 100; ibase=2; 1000.0001111*1100100; obase=1010; 1100101011.101110000000000000000000;'|bc 1000.0001111 ### 8.12 1100100 ### 100 1100101011.101110000000000000000000 ### 8.12 * 100 811.718750000000000000000000 ### = BTW: obase=1010; weil auch dort 'ibase=2' gilt ;) Jetzt sollte auch klar sein, warum mit '%d' 811 ausgegeben wird. BTW: $ perl -e 'printf "%d, %d\n", 811.718750000000000000000000, 8.12*100;' 811, 811 Noch Fragen? -dnh -- Who are you? What do you want? Why are you here? -- Babylon 5 -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
participants (4)
-
Alexander Beck-Ratzka
-
David Haller
-
Kyek, Andreas, VF-DE
-
Werner Flamme