Thread Kaufmännisch korrekt runden
(67 answers)
Opened by bianca at 2009-12-11 07:14
Um das etwas zu illustrieren:
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 #!/usr/bin/perl use strict; use warnings; ######################################################################################### ######################################################################################### sub kfmrunden_topeg { my $zahl=shift; return undef unless(defined($zahl)); my $stelle=shift || 0; # prepare for Xe[+-]Y Notation # handle big float my ($pre,$number,$exponent)=$zahl=~/^([-+]?)([\d.]+)(?:e([+-]?\d+))?$/; $exponent=0 unless defined($exponent); $pre='' if(!$pre || $pre ne '-'); # full integer number with exponent my ($l)=$number=~/\.(.+)$/; $exponent-=$l?length($l):0; $number=~y/.//d; # correct position for round my $stellen=$stelle+$exponent; if($stellen<0) { $exponent=-$stelle; my $add=substr(('0'x abs($stellen)).$number,$stellen,-$stellen); # round... $number+=$add; $number=('0'x abs($stellen)).sprintf("%.0f",$number); substr($number,$stellen,-$stellen,''); } # reconstruct number $zahl="$pre${number}e$exponent"; #$zahl=sprintf("%.${stelle}f",$zahl); return $zahl+0; } sub neueloesung { my $num = shift (@_) || 0; my $stellen = shift (@_) || 0; my $rounded = '0'; if ($stellen >= 0 && $stellen <= 9 && !($num =~ /[^-\.0-9]/)) { $rounded = int ($num * (10 ** $stellen) + ($num < 0 ? -0.5 : 0.5) ) / 10 ** $stellen; } return $rounded; } ######################################################################################### ######################################################################################### my @subs=('kfmrunden_topeg','neueloesung'); ######################################################################################### ######################################################################################### sub tests { my $sub=shift; $sub=\&$sub; my $cnt=0; for my $i (0..200) { my $stellen=9; my $wert="0.".substr(("0"x($stellen+1)).($i*5),-($stellen+1),($stellen+1)); $cnt++ if(($i*5)%10); my $erwartet = "0.".substr(("0"x($stellen+1)).($cnt*10),-($stellen+1),($stellen+1)) +0; my $gerundet=$sub->($wert,$stellen); printout($wert,$erwartet,$gerundet,$stellen); }; print "#"x80,"\n"; $cnt=1; my $erwartet=0.01; my $wert=0.005; for my $i (0..200) { my $stellen=2; my $gerundet=$sub->($wert,$stellen); printout($wert,$erwartet,$gerundet,$stellen); $wert+=0.005; if($cnt==2) { $erwartet+=0.01; $cnt=0; } $cnt++; }; print "#"x80,"\n"; } sub printout { my $wert=shift; my $soll=shift; my $ist=shift; my $stellen=shift; $soll=sprintf("%0.${stellen}f",$soll); $ist=sprintf("%0.${stellen}f",$ist); my $space = '.' x 25; print "\'$wert\'" . substr ($space,0,25 - length ($wert)) . "auf $stellen Stelle(n): \'$ist\'" . substr ($space,0,25 - length ($ist)) . ($soll == $ist ? ' OK' : " FEHLER! Erwartet \'$soll\'") . "\n"; } ######################################################################################### ######################################################################################### for my $sub (@subs) { print "SUB $sub\n"; tests($sub); print "#"x80,"\n"; print "#"x80,"\n"; print "#"x80,"\n"; } Das Interessante heraus gepickt: Code: (dl
)
1 SUB neueloesung EDIT: Kleinen Fehler beseitigt der das erkennen bestimmter Zahlen in meiner Rundungs-Funktion verhinderte. Last edited: 2009-12-12 22:20:28 +0100 (CET) |