Zahlen runden mit Math::Round
Veröffentlicht von Thomas Fahle am (Permalink)
Zahlen runden kann eine recht tückische Aufgabe sein.
Das CPAN-Modul Math::Round von Geoffrey Rommel vereinfacht diese Aufgabe erheblich.
Dieser Beitrag geht auf die Themen
- Auf Ganze Zahlen runden
- Auf Fließkommazahlen runden, z.B. Nachkommastellen
- Zum nächsten Vielfachen auf- oder abrunden, z.B. Hunderter
Auf Ganze Zahlen runden
Die Prozeduren round, round_even, round_odd und round_rand runden auf Ganzzahlen (Integer) auf bzw. ab.
- round LIST rundet zur nächsten Ganzzahl auf bzw. ab.
- round_even LIST rundet zur nächsten Ganzzahl auf bzw. ab. Zahlen, die in der Mitte zwischen zwei Ganzzahlen liegen, werden zur nächsten geraden Zahl gerundet.
- round_odd LIST rundet zur nächsten Ganzzahl auf bzw. ab. Zahlen, die in der Mitte zwischen zwei Ganzzahlen liegen, werden zur nächsten ungeraden Zahl gerundet.
- round_rand LIST rundet zur nächsten Ganzzahl auf bzw. ab. Zahlen, die in der Mitte zwischen zwei Ganzzahlen liegen, werden zufällig auf- bzw. abgerundet
Beispiel: Zur nächsten Ganzzahl auf- oder abrunden:
#!/usr/bin/perl use strict; use warnings; use Math::Round qw/round/; my @zahlen = qw /-2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 125.3456 125.5678/; foreach my $zahl ( @zahlen ) { printf("%8s wird zu %8s gerundet\n", $zahl, round($zahl)); }
Das Programm erzeugt folgende Ausgabe:
-2.5 wird zu -3 gerundet -2.0 wird zu -2 gerundet -1.5 wird zu -2 gerundet -1.0 wird zu -1 gerundet -0.5 wird zu -1 gerundet 0.0 wird zu 0 gerundet 0.5 wird zu 1 gerundet 1.0 wird zu 1 gerundet 1.5 wird zu 2 gerundet 2.0 wird zu 2 gerundet 2.5 wird zu 3 gerundet 125.3456 wird zu 125 gerundet 125.5678 wird zu 126 gerundet
Beispiel: round_even
#!/usr/bin/perl use strict; use warnings; use Math::Round qw/round_even/; my @zahlen = qw /-2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 125.3456 125.5678/; foreach my $zahl ( @zahlen ) { printf("%8s wird zu %8s gerundet\n", $zahl, round_even($zahl)); }
Das Programm erzeugt folgende Ausgabe:
-2.5 wird zu -2 gerundet -2.0 wird zu -2 gerundet -1.5 wird zu -2 gerundet -1.0 wird zu -1 gerundet -0.5 wird zu 0 gerundet 0.0 wird zu 0 gerundet 0.5 wird zu 0 gerundet 1.0 wird zu 1 gerundet 1.5 wird zu 2 gerundet 2.0 wird zu 2 gerundet 2.5 wird zu 2 gerundet 125.3456 wird zu 125 gerundet 125.5678 wird zu 126 gerundet
Beispiel: round_odd
#!/usr/bin/perl use strict; use warnings; use Math::Round qw/round_odd/; my @zahlen = qw /-2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 125.3456 125.5678/; foreach my $zahl ( @zahlen ) { printf("%8s wird zu %8s gerundet\n", $zahl, round_odd($zahl)); }
Das Programm erzeugt folgende Ausgabe:
-2.5 wird zu -3 gerundet -2.0 wird zu -2 gerundet -1.5 wird zu -1 gerundet -1.0 wird zu -1 gerundet -0.5 wird zu -1 gerundet 0.0 wird zu 0 gerundet 0.5 wird zu 1 gerundet 1.0 wird zu 1 gerundet 1.5 wird zu 1 gerundet 2.0 wird zu 2 gerundet 2.5 wird zu 3 gerundet 125.3456 wird zu 125 gerundet 125.5678 wird zu 126 gerundet
Beispiel: round_rand
#!/usr/bin/perl use strict; use warnings; use Math::Round qw/round_rand/; # Messbereich (Anzahl der Messungen); my $von = 1; my $bis = 10_000; # Die Zahl, die gemessen/geprüft wird my $zahl = 2.5; # Zaehler fuer Anzahl der Messungen my $anzahl_messungen = 0; # Container fuer die Messergebnisse my %messergebnis = (); for ( $von .. $bis ) { my $gerundet = round_rand($zahl); $messergebnis{$gerundet}++; $anzahl_messungen++; } my @messwerte = keys %messergebnis; foreach my $messwert (@messwerte) { print "$zahl wurde $messergebnis{$messwert} mal zu $messwert gerundet.\n"; print "Das entspricht ", $messergebnis{$messwert} / $anzahl_messungen * 100 , "%.\n"; }
Das Programm erzeugt folgende Ausgabe:
2.5 wurde 5044 mal zu 3 gerundet. Das entspricht 50.44%. 2.5 wurde 4956 mal zu 2 gerundet. Das entspricht 49.56%.
Runden auf Ganzzahlen im Vergleich
Das folgende Beispiel erstellt eine kleine tabellarische Übersicht, die den Vergleich der vorgestellten Prozeduren vereinfachen soll.
#!/usr/bin/perl use strict; use warnings; use Math::Round qw/round round_even round_odd round_rand/; my @zahlen = qw /-2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 /; # Format für printf my $format = '%6s %6s %10s %10s %10s'; printf("$format\n", 'Zahl', 'round', 'round_even', 'round_odd', 'round_rand'); foreach my $zahl ( @zahlen ) { printf("$format\n", $zahl, round($zahl), round_even($zahl), round_odd($zahl), round_rand($zahl) ); }
Das Programm erzeugt folgende Ausgabe:
Zahl round round_even round_odd round_rand -2.5 -3 -2 -3 -3 -2.0 -2 -2 -2 -2 -1.5 -2 -2 -1 -2 -1.0 -1 -1 -1 -1 -0.5 -1 0 -1 0 0.0 0 0 0 0 0.5 1 0 1 1 1.0 1 1 1 1 1.5 2 2 1 2 2.0 2 2 2 2 2.5 3 2 3 2
Auf Fließkommazahlen runden
Hier bietet sich nearest(TARGET, LIST) an. nearest rundet zum Vielfachen von TARGET auf bzw. ab.
Beispiel: Auf eine bzw. zwei Nachkommastellen runden
#!/usr/bin/perl use strict; use warnings; use Math::Round qw/nearest/; my @zahlen = qw /-2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 125.3456 125.5678/; my $format = '%8s %8s %8s'; printf("$format\n", 'Zahl', 'Eine NK', 'Zwei NK' ); foreach my $zahl ( @zahlen ) { # Eine Nachkommastelle (0.1) # Zwei Nachkommastellen (0.01) printf("$format\n", $zahl, nearest('0.1',$zahl), nearest('0.01',$zahl) ); }
Das Programm erzeugt folgende Ausgabe:
Zahl Eine NK Zwei NK -2.5 -2.5 -2.5 -2.0 -2 -2 -1.5 -1.5 -1.5 -1.0 -1 -1 -0.5 -0.5 -0.5 0.0 0 0 0.5 0.5 0.5 1.0 1 1 1.5 1.5 1.5 2.0 2 2 2.5 2.5 2.5 125.3456 125.3 125.35 125.5678 125.6 125.57
Zum nächsten Vielfachen auf- oder abrunden
Die beiden Prozeduren nlowmult und nhimult runden zum nächsten kleineren bzw. größerem Vielfachen ab bzw. auf.
- nlowmult TARGET, LIST rundet zum nächsten kleineren Vielfachen ab.
- nhimult TARGET, LIST rundet zum nächsten größeren Vielfachen auf.
Beispiel: Auf volle 100er auf- bzw. abrunden.
#!/usr/bin/perl use strict; use warnings; use Math::Round qw/nlowmult nhimult/; my @zahlen = qw/ 126 176/; # Auf volle 100er auf- bzw. abrunden my $target = 100; my $format = '%6s %10s %10s'; printf("$format\n", 'Zahl', 'nlowmult', 'nhimult'); foreach my $zahl (@zahlen) { printf("$format\n", $zahl, nlowmult($target,$zahl), nhimult($target,$zahl) ); }
Das Programm erzeugt folgende Ausgabe:
Zahl nlowmult nhimult 126 100 200 176 100 200
Das funktioniert auch mit Vielfachen von Fließkommazahlen. Probieren Sie es einfach mal aus.
Siehe auch
- Math::Round
- Math::SigFigs
- Math::BigInt
- Wikipedia: Rundung
- perldoc: sprintf
- perldoc: printf
- perldoc: Posix
- Perl FAQ 4.13 - Does perl have a round function? What about ceil() and floor()?
- PerlCommunityWiki » Wissensbasis » PerlTutorialKapitel5
- Perlmonks: How do I round a number?
- Perlmonks: How do I round up a number?