Thread Kaufmännisch korrekt runden (67 answers)
Opened by bianca at 2009-12-11 07:14

bianca
 2009-12-11 07:14
#129173 #129173
User since
2009-09-13
6977 Artikel
BenutzerIn

user image
Bin mal wieder an meiner Lieblingsbeschäftigung :)

Mein aktueller Status Quo sieht so aus:
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
sub kfmrunden {
        #
        # Aufruf:
        # =======
        # my $gerundet = &kfmrunden([wert],[stellen]);
        # [wert]                = Nur nummerische Werte! Keine Extremwerte wie z.B. 1e+100 oder 4.24306121591708e-007! Kein Komma, kein Tausenderpunkt etc.
        # [stellen]             = Anzahl gewünschte Nachkommastellen, zwischen 0 und 9 zulässig
        #
        my $wert = shift (@_) || 0;
        my $stellen = shift (@_) || 0;
        my $vorzeichen = '';
        my $vorkomma = 0;
        my $nachkomma = '';
        if ($stellen >= 0 && $stellen <= 9 && !($wert =~ /[^+-\.0-9]/)) {
                if (substr ($wert,0,1) eq '-' || substr ($wert,0,1) eq '+') {
                        $vorzeichen = '-' if substr ($wert,0,1) eq '-';
                        $wert = substr ($wert,1);
                }
                ($vorkomma,$nachkomma) = split /\./,$wert;
                $vorkomma = 0 unless $vorkomma;
                $nachkomma = '' unless $nachkomma;
                if (length ($nachkomma) > $stellen) {
                        my $auf = (substr ($nachkomma,$stellen,1) > 4 ? 1 : 0);
                        if (!$stellen) {
                                $vorkomma ++ if $auf;
                                $nachkomma = '';
                        }
                        else {
                                if ($auf) {
                                        $nachkomma = substr ($nachkomma,0,$stellen) + 1;
                                        if (length ($nachkomma) > $stellen) {
                                                $vorkomma ++;
                                                $nachkomma = '';
                                        }
                                        else {
                                                $nachkomma = substr ($nachkomma,0,$stellen);
                                        }
                                }
                                else {
                                        $nachkomma = substr ($nachkomma,0,$stellen);
                                }
                        }
                }
        }
        return "$vorzeichen$vorkomma" . ($nachkomma ne '' ? ".$nachkomma" : '');
}


Meine Testumgebung sieht so aus:
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
my $sub = 'kfmrunden';
my %test =      (
(.57 * 100) . ',2'                      => 57,
'1.295,2'                                       => 1.3,
'9.999,3'                                       => 9.999,
'9.999,2'                                       => 10,
'9.999,1'                                       => 10,
'9.999,0'                                       => 10,
'8.9964,2'                                      => 9,
'8.9964,0'                                      => 9,
'8.9964,1'                                      => 9,
'1,2'                                           => 1,
'1.455,2'                                       => 1.46,
'1.9,0'                                         => 2,
'12345.34,1'                            => 12345.3,
'12345.35,1'                            => 12345.4,
'12.2345678905,9'                       => 12.234567891,
'.5678,3'                                       => .568,
'4.24306121591708e-007,2'       => 0,
'1e+100,3'                                      => 0,
'.5674,3'                                       => .567,
'.5670,3'                                       => .567,
'456.4,0'                                       => 456,
'456.5,0'                                       => 457,
'0.49999999,0'                          => 0,
'0.999999999,0'                         => 1,
'0.5,0'                                         => 1,
'999999999999.999,2'            => 1000000000000,
'999999999999.994,2'            => 999999999999.99,
'00000034.999,2'                        => 35,
                        );

my $space = '.' x 25;
foreach my $test (sort {(split /,/,$a)[0] <=> (split /,/,$b)[0] } keys %test) {
        foreach my $multi (1,-1) {
                my ($wert,$stellen) = split /,/,$test;
                $wert = $wert * $multi;
                my $erwartet = $test{$test} * $multi;
                my $gerundet = &{$sub} ($wert,$stellen);
                print "\'$wert\'" . substr ($space,0,25 - length ($wert)) . "auf $stellen Stelle(n): \'$gerundet\'" . substr ($space,0,25 - length ($gerundet)) . ($gerundet == $erwartet ? ' OK' : " FEHLER! Erwartet \'$erwartet\'") . "\n";
        }
}


Wollte fragen, ob jemand Lust hat, mit zu testen, ob nicht doch noch ein Fehler drin ist und vielleicht etwas Code- und Geschwindigkeitsoptimieren.
Danke
10 print "Hallo"
20 goto 10

View full thread Kaufmännisch korrekt runden