1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
sub integer { my $wert = shift ( @_ ) || 0; if ($wert =~ /e\-\d+$/) { return 0; } if ($wert =~ /\./) { my $neu = ''; for (my $st = 0; $st < length($wert); $st ++) { if (substr($wert,$st,1) eq '.') { last; } else { $neu .= substr($wert,$st,1); } } $neu = 0 if $neu eq ''; $wert = $neu; $wert = 0 if $wert == -0; } return $wert; }
2013-03-01T15:37:18 bianca
2013-03-01T17:15:29 GUIfreundint schneidet gnadenlos ab (Rundung Richtung Null).
2013-03-01T17:15:29 GUIfreundsprintf '%.0f' rundet zur nächsten Integer.
2013-03-01T17:15:29 GUIfreund@bianca:
Versuch's doch mal mit sprintf '%.0f'. Das dürfte das liefern, was du brauchst.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
#!/usr/bin/perl use strict; use warnings; my $space = '.' x 25; my ($int,$erwartet); foreach my $test ( -19854.94 - -3970.99 - -15883.95,'=0', .57 * 100,'=57', .58,'=0', 12.345,'=12', 57.00000000000000001,'=57', 0.000000000000001,'=0', 1.01205,'=1', -0.903,'=0', -1.9999999 + .000000099999999,'=-1' ) { if (substr ($test,0,1) eq '=') { $erwartet = substr($test,1); print "Erwartet '$erwartet'\n\n"; } else { $int = GUIfreund($test); print "\'$test\'".substr($space,0,25 - length ($test))."geINTet mit GUIfreund: \'$int\'".substr($space,0,25 - length ($int))."\n"; $int = integer($test); print "\'$test\'".substr($space,0,25 - length ($test))."geINTet mit Bianca : \'$int\'".substr($space,0,25 - length ($int))."\n"; } } ############################################################################### sub GUIfreund { sprintf('%.0f',$_[0]); } sub integer { my $wert = shift ( @_ ) || 0; if ($wert =~ /e\-\d+$/) { return 0; } if ($wert =~ /\./) { my $neu = ''; for (my $st = 0; $st < length($wert); $st ++) { if (substr($wert,$st,1) eq '.') { last; } else { $neu .= substr($wert,$st,1); } } $neu = 0 if $neu eq ''; $wert = $neu; $wert = 0 if $wert == -0; } return $wert; }
Quote'1.81898940354586e-012'....geINTet mit GUIfreund: '0'........................
'1.81898940354586e-012'....geINTet mit Bianca : '0'........................
Erwartet '0'
'57'.......................geINTet mit GUIfreund: '57'.......................
'57'.......................geINTet mit Bianca : '57'.......................
Erwartet '57'
'0.58'.....................geINTet mit GUIfreund: '1'........................
'0.58'.....................geINTet mit Bianca : '0'........................
Erwartet '0'
'12.345'...................geINTet mit GUIfreund: '12'.......................
'12.345'...................geINTet mit Bianca : '12'.......................
Erwartet '12'
'57'.......................geINTet mit GUIfreund: '57'.......................
'57'.......................geINTet mit Bianca : '57'.......................
Erwartet '57'
'1e-015'...................geINTet mit GUIfreund: '0'........................
'1e-015'...................geINTet mit Bianca : '0'........................
Erwartet '0'
'1.01205'..................geINTet mit GUIfreund: '1'........................
'1.01205'..................geINTet mit Bianca : '1'........................
Erwartet '1'
'-0.903'...................geINTet mit GUIfreund: '-1'.......................
'-0.903'...................geINTet mit Bianca : '0'........................
Erwartet '0'
'-1.9999998'...............geINTet mit GUIfreund: '-2'.......................
'-1.9999998'...............geINTet mit Bianca : '-1'.......................
Erwartet '-1'
2013-03-01T18:33:33 biancaDas verstehe ich jetzt nicht. Hatten wir nicht damals schon festgestellt, dass dein sprintf() nicht ausreicht? Du warst doch beteiligt damals, oder nicht?
1 2 3 4
sub GUIfreund { use POSIX qw(floor ceil); return $_[0] > 0 ? floor($_[0]) : ceil($_[0]); }
1
2
3
'57'.......................geINTet mit GUIfreund: '56'.....
'57'.......................geINTet mit Bianca : '57'.....
Erwartet '57'
1
2
3
'57'.......................geINTet mit GUIfreund: '57'.....
'57'.......................geINTet mit Bianca : '57'.....
Erwartet '57'
1 2 3 4
print "geINTet mit GUIfreund: \'$int\'".substr($space,0,15 - length ($int)); printf "Eingabe %.15f\n", $test; print "geINTet mit Bianca : \'$int\'".substr($space,0,15 - length ($int)); printf "Eingabe %.15f\n", $test;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
geINTet mit GUIfreund: '0'..............Eingabe 0.000000000001819
geINTet mit Bianca : '0'..............Eingabe 0.000000000001819
Erwartet '0'
geINTet mit GUIfreund: '56'.............Eingabe 56.999999999999993
geINTet mit Bianca : '57'.............Eingabe 56.999999999999993
Erwartet '57'
geINTet mit GUIfreund: '0'..............Eingabe 0.580000000000000
geINTet mit Bianca : '0'..............Eingabe 0.580000000000000
Erwartet '0'
geINTet mit GUIfreund: '12'.............Eingabe 12.345000000000001
geINTet mit Bianca : '12'.............Eingabe 12.345000000000001
Erwartet '12'
geINTet mit GUIfreund: '57'.............Eingabe 57.000000000000000
geINTet mit Bianca : '57'.............Eingabe 57.000000000000000
Erwartet '57'
geINTet mit GUIfreund: '0'..............Eingabe 0.000000000000001
geINTet mit Bianca : '0'..............Eingabe 0.000000000000001
Erwartet '0'
geINTet mit GUIfreund: '1'..............Eingabe 1.012050000000000
geINTet mit Bianca : '1'..............Eingabe 1.012050000000000
Erwartet '1'
geINTet mit GUIfreund: '0'..............Eingabe -0.903000000000000
geINTet mit Bianca : '0'..............Eingabe -0.903000000000000
Erwartet '0'
geINTet mit GUIfreund: '-1'.............Eingabe -1.999999800000001
geINTet mit Bianca : '-1'.............Eingabe -1.999999800000001
Erwartet '-1'
2013-03-04T18:16:03 GUIfreundDann habe ich die prints etwas geändert, um den Testwert in der möglichst vollen Genauigkeit zu sehen.
2013-03-05T05:56:50 bianca2013-03-04T18:16:03 GUIfreundDann habe ich die prints etwas geändert, um den Testwert in der möglichst vollen Genauigkeit zu sehen.
Und das tust du wiederum mit printf() von dem wir doch wissen, dass es in diesem Bereich nicht wie benötigt arbeitet.
((1 - 0.9999) * 10000)
2013-03-05T12:09:12 MuffiEin ganz simples Beispiel, das ziemlich viele Bits "klaut"
Code (perl): (dl )((1 - 0.9999) * 10000)
Das sollte 1 ergeben.
1
2
3
4
$ perl -E'say sprintf("%.13f",((1 - 0.9999) * 10000))'
0.9999999999999
$ perl -E'say sprintf("%.12f",((1 - 0.9999) * 10000))'
1.000000000000
1
2
3
4
$ perl -E'say sprintf("%.18f",0.125)'
0.125000000000000000
$ perl -E'say sprintf("%.18f",0.25)'
0.250000000000000000
2013-03-05T14:45:57 RaubtierSorry, was meinst du mit das mit "das gibt nur mit sprintf korrekt 1"?
2013-03-05T14:45:57 RaubtierWenn man was genaueres will, dann muss man eben eine Bibliothek nehmen, die exakt rechnet.
2013-03-05T16:43:29 bianca2013-03-05T14:45:57 RaubtierWenn man was genaueres will, dann muss man eben eine Bibliothek nehmen, die exakt rechnet.
Brauche ich. Was empfiehlst du?
2013-03-05T12:09:12 MuffiEs gibt auch kein Grundrauschen der Gleitkommaarithmetik.
2013-03-05T12:09:12 MuffiSubtraktion: Bei fast gleich großen Zahlen ..... Da kanns gefährlich werden
2013-03-05T18:09:35 GUIfreundDeshalb bewundere ich biancas int-Routine um so mehr.
2013-03-05T18:09:35 GUIfreundIch war freilich überzeugt, dass auch diese nicht perfekt ist. Vielen Dank an Muffi für das Beispiel.
1 2
my $epsilon = 5e-13; # das was du als Toleranz ansiehst return floor($_[0] + $epsilon);
2013-03-01T18:44:17 GwenDragon(s)printf ist KEINE Integer- und auch keine Rundungsfunktion![...]Schlecht für Anfänger, wenn die sowas falsch lernen.
2013-03-01T18:44:17 GwenDragon(s)printf ist KEINE Integer- und auch keine Rundungsfunktion!
Es formatiert nur Zahlen nach einem bestimmten Ausgabeformat!
2013-03-01T18:44:17 GwenDragonNicht so sonderlich sinnvoll printf als Methode zur Erzwingung einer Ganzzahl anzupreisen. Schlecht für Anfänger, wenn die sowas falsch lernen.
Nicht nur die Ariane 5 stürzte wegen so einem Unsinn ab. Auch Patriots und anderes waren Opfer von falscher Berechnung.
$ganz = sprintf ('%.0f', $wert) + 0;
Quoteint schneidet gnadenlos ab (Rundung Richtung Null).
sprintf '%.0f' rundet zur nächsten Integer.
floor (in POSIX) rundet zur nächstkleineren Integer (nach links).
ceil (in POSIX) rundet zur nächstgrößeren Integer (nach rechts).
2013-03-02T18:02:16 GUIfreundIch hatte bianca falsch verstanden
2013-03-02T17:39:58 GwenDragonOh, wir diskutieren jetzt außerhalb des Themas des Threaderstellers.
Quote(s)printf ist KEINE Integer- und auch keine Rundungsfunktion!
Es formatiert nur Zahlen nach einem bestimmten Ausgabeformat!
2013-03-01T10:29:49 Rolf_PlusWnur die 19.9 macht Probleme.
1 2 3 4 5 6 7
sub integer { my $wert = shift ( @_ ) || 0; return 0 if $wert =~ /e[+\-]?\d+$/; $wert=$1 if $wert =~ /^(.*?)\./; $wert=0 unless $wert; return $wert; }
Guest werWarum nur so kompliziert?
Quote'-0.903'...................geINTet mit PC : '0'........................
'-0.903'...................geINTet mit gast_wer : '-0'.......................
'-0.903'...................geINTet mit GUIfreund: '-1'.......................
'-0.903'...................geINTet mit Bianca : '0'........................
Erwartet '0'
'1e+015'...................geINTet mit PC : '1e+015'...................
'1e+015'...................geINTet mit gast_wer : '0'........................
'1e+015'...................geINTet mit GUIfreund: '1000000000000000'.........
'1e+015'...................geINTet mit Bianca : 'FEHLER'...................
Erwartet 'FEHLER'
1 2 3 4 5 6 7 8
sub integer { my $wert = shift ( @_ ) || 0; return 'FEHLER' if $wert =~ /e+?\d+$/; return 0 if $wert =~ /e-\d+$/; $wert=$1 if $wert =~ /^(.*?)\./; $wert=0 if !$wert or $wert == -0; return $wert; }
Quote'1e+015'...................geINTet mit PC : '1e+015'...................
'1e+015'...................geINTet mit gast_wer : '1e+015'...................
'1e+015'...................geINTet mit GUIfreund: '1000000000000000'.........
'1e+015'...................geINTet mit Bianca : 'FEHLER'...................
Erwartet 'FEHLER'
1 2 3 4 5 6 7 8
sub integer { my $wert = shift ( @_ ) || 0; return 'FEHLER' if $wert =~ /e\+?\d+$/; return 0 if $wert =~ /e-\d+$/; $wert=$1 if $wert =~ /^(.*?)\./; $wert=0 if !$wert or $wert == -0; return $wert; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14
use utf8; sub integer { my $wert = shift ( @_ ) || 0; return 'FEHLER' if $wert =~ /e\+?\d+$/; return 0 if $wert =~ /e-\d+$/; $wert=$1 if $wert =~ /^(.*?)\./; $wert=0 if !$wert or $wert == -0; return $wert; } print integer( 'e-߉' ), "\n"; # 0
2013-03-03T22:56:32 rostiZ.B. funktioniert die Berechnung fortlaufender Tage nach den Formeln von JJ Scaliger nur mit use integer, die Funktion int() ist hierfür völlig unbrauchbar.
1
2
3
4
$ perl -E'use integer;say 9223372036854775807+5'
-9223372036854775804
$ perl -E'say 9223372036854775807+5'
9223372036854775812
2013-03-03T22:56:32 rostiEs kommt für mich als Praktiker darauf an, was eigentlich gemacht werden soll
QuoteAnsonsten weiß ich nicht, was deine ständigen PHP-Vergleiche bringen sollen.
2013-03-04T10:01:14 rostiDann kann ich auch noch folgende zur Lösung aufbieten: COBOL, Fortran, Python, JSP oder Ruby.QuoteAnsonsten weiß ich nicht, was deine ständigen PHP-Vergleiche bringen sollen.
(...)
Ich vermute (ganz stark!), dass sich hinter der Anforderung von Rolf+ eine praktische Angelegenheit verbirgt. D.h., dass es evntl. möglich ist, mit einer anderen Programmiersprache, wie zum Beispiel PHP, dieser Anforderung besser beikommen zu können.