Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]12542[/thread]

Runden auf zwei relevante Stellen?!

Leser: 1


<< >> 9 Einträge, 1 Seite
Ronnie
 2008-09-24 23:49
#114907 #114907
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Ich generiere eine größere Liste Beispielaufgaben. Ich würde gerne die berechneten Ergebnisse vernünftig runden. Es sind etliche dabei, wie 0.000124687 - die ich gerne auf zwei oder drei relevante Stellen runden würde, also 0.000125. Da die Ergebnisse aber unterschiedlich groß sind (einige Zehnerpotenzen), kommt sprintf wohl nicht in Frage. Hat jemand 'ne bessere Idee (Regexp evtl.)?
Linuxer
 2008-09-25 00:36
#114908 #114908
User since
2006-01-27
3890 Artikel
HausmeisterIn

user image
in Auf 2 Nachkommastellen mit perl runden findet sich ein weiterer Verweis auf eine ähnliche Diskussion. Vielleicht findest Du dort passende Ideen.
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
moritz
 2008-09-25 00:39
#114909 #114909
User since
2007-05-11
923 Artikel
HausmeisterIn
[Homepage]
user image
Wenn du nichts gegen Exponentendarstellung hast:

Code: (dl )
1
2
$ perl -wle 'printf "%.2e\n", 0.000000124687'
1.25e-07

betterworld
 2008-09-25 00:39
#114910 #114910
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Hm, vielleicht so:
Code: (dl )
1
2
% perl -lwe 'print sprintf("%.2e", 0.000124687)+0'
0.000125
Ronnie
 2008-09-25 01:29
#114912 #114912
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Etwas umständlich, aber es tut erstmal:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sub to_three_sig_digits {
    my $val = shift;
    if ($val =~ /^(0\.0*)(\d+)$/) {
        my $pre = $1;
        my $app = $2;
        return $val if length($app) <= 3;

        my $digits = substr($app, 0, 3);
        my $fourth = substr($app, 3, 1);
        $digits += 1 if $fourth >= 5;
        $val = $pre . $digits;
    } elsif ($val > 1) {
        $val = sprintf("%.2f", $val);
    } 
    return $val;
}
topeg
 2008-09-25 21:42
#114935 #114935
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ich habe es mir nicht nehmen lassen auch was zu schreiben:
Code (perl): (dl )
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
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/perl

use strict;
use warnings;

my $signifikant=3;

my $z="10.000000128536";
print "$z --> ".round_significant($z,$signifikant)."\n";

$z="10.000001117885000001100000";
print "$z --> ".round_significant($z,$signifikant)."\n";

$z="0.000000195675";
print "$z --> ".round_significant($z,$signifikant)."\n";

$z="0.1000000195675";
print "$z --> ".round_significant($z,$signifikant)."\n";

$z="1000.1399999";
print "$z --> ".round_significant($z,$signifikant)."\n";

$z="1000.00099999";
print "$z --> ".round_significant($z,$signifikant)."\n";

$z="1000.00090000019999";
print "$z --> ".round_significant($z,$signifikant)."\n";

$z="1000.99999";
print "$z --> ".round_significant($z,$signifikant)."\n";

$z="1099.99999";
print "$z --> ".round_significant($z,$signifikant)."\n";

$z="9999.9999999";
print "$z --> ".round_significant($z,$signifikant)."\n";

##########################################################
##########################################################
sub round_significant
{
  my $zahl=shift;
  my $stelle=shift;

  if(my ($zv,$zn) = $zahl =~/^([\d\.]+0)([1-9]{$stelle})\d*?$/)
  {
   $zv.="0"x$stelle;
   $zn++;
   my $l=length($zn);
   substr($zv,-1*$l,$l,$zn);
   $stelle--;
   $zv=~s/(\.\d{$stelle,}[1-9]+)0+$/$1/;
   $zahl=$zv;
  }
  else
  { $zahl= sprintf("%.${stelle}f",$zahl); }

  return $zahl;
}
betterworld
 2008-09-26 01:39
#114938 #114938
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Ronnie+2008-09-24 23:29:12--
Etwas umständlich, aber es tut erstmal:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sub to_three_sig_digits {
    my $val = shift;
    if ($val =~ /^(0\.0*)(\d+)$/) {
        my $pre = $1;
        my $app = $2;
        return $val if length($app) <= 3;

        my $digits = substr($app, 0, 3);
        my $fourth = substr($app, 3, 1);
        $digits += 1 if $fourth >= 5;
        $val = $pre . $digits;
    } elsif ($val > 1) {
        $val = sprintf("%.2f", $val);
    } 
    return $val;
}

Das rundet mir jetzt 0.9999 zu 0.1000, das erscheint mir falsch.

Dass Du fuer Werte, die größer als 1 sind, immer auf zwei Nachkommastellen (also nicht nur zwei relevante Stellen) runden willst, wusste ich nicht. Aber ansonsten wuerde ich gerne fragen, was gegen meine (einfachere) Lösung von oben spricht.
Ronnie
 2008-09-26 02:47
#114939 #114939
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Hallo Betterworld,
betterworld+2008-09-25 23:39:43--
Das rundet mir jetzt 0.9999 zu 0.1000, das erscheint mir falsch.

Ist es auch - war auf die Schnelle zusammengestrickt.
betterworld+2008-09-25 23:39:43--
Dass Du fuer Werte, die größer als 1 sind, immer auf zwei Nachkommastellen (also nicht nur zwei relevante Stellen) runden willst, wusste ich nicht. Aber ansonsten wuerde ich gerne fragen, was gegen meine (einfachere) Lösung von oben spricht.

Nichts, die ist super! Ich habe sie beim ersten lesen als Exponenten-Darstellung interpretiert, die ich vermeiden wollte. Allerdings ist mir im Moment auch nicht klar wie sie funktioniert?!

Gruß,
Ronnie
betterworld
 2008-09-26 15:51
#114951 #114951
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Ronnie+2008-09-26 00:47:00--
Allerdings ist mir im Moment auch nicht klar wie sie funktioniert?!


Ich weiß nicht so ganz, wie ich es erklären soll...
Letztendlich ist ja 1.25e-2 und 0.0125 dieselbe Zahl. Perl wuerde fuer eine Zahl immer die zweite Darstellung waehlen (jedenfalls in einem gewissen Bereich); das erste kann nur ausgegeben werden, wenn es als String gespeichert ist. Einen String zu einer Zahl machen geht mit "+0".

Was ich an meiner Loesung unschoen finde, ist nur, dass es 1.0001 zu "1" macht, huebscher waere "1.000".
<< >> 9 Einträge, 1 Seite



View all threads created 2008-09-24 23:49.