2009-01-30 3 views
11

In Perl scheint der Operator % ganze Zahlen anzunehmen. Zum Beispiel:Wie berechnen Sie Div und Mod von Fließkommazahlen?

sub foo { 
    my $n1 = shift; 
    my $n2 = shift; 
    print "perl's mod=" . $n1 % $n2, "\n"; 
    my $res = $n1/$n2; 
    my $t = int($res); 
    print "my div=$t", "\n"; 
    $res = $res - $t; 
    $res = $res * $n2; 
    print "my mod=" . $res . "\n\n"; 
} 

foo(3044.952963, 7.1); 
foo(3044.952963, -7.1); 
foo(-3044.952963, 7.1); 
foo(-3044.952963, -7.1); 

gibt

perl's mod=6 
my div=428 
my mod=6.15296300000033 

perl's mod=-1 
my div=-428 
my mod=6.15296300000033 

perl's mod=1 
my div=-428 
my mod=-6.15296300000033 

perl's mod=-6 
my div=428 
my mod=-6.15296300000033 

Nun, wie Sie sehen können, habe ich für die Berechnung div und mod mit einer „Lösung“ schon kommen. Was ich jedoch nicht verstehe, ist, welche Wirkung das Vorzeichen jedes Arguments auf das Ergebnis haben sollte. Wäre nicht die div immer positiv, wie oft n2 in n1 passt? Wie soll die Arithmetik in dieser Situation funktionieren?

Antwort

8

Bei a = qd + r gibt es eine Mehrdeutigkeit bei der Berechnung des Rests für negative Werte von d. −42 = 9×(−5) + 3 oder −42 = 8×(−5) + (−2):

Z. B .:

Der Ausdruck −42 ÷ −5, kann entweder als ausgedrückt werden.

Also der Rest ist dann entweder 3 oder -2.

Für weitere Informationen: Wikipedia:Remainder "Inequality satisfied by the remainder"

Auch der Ausgang bei negativen Zahlen in mod/div ist abhängig von der Implementierung in Software-Sprachen. Siehe Wikipedia: Modulo operation (siehe Tabelle rechts)

+0

Für den mathematischen Hintergrund finden Sie unter [modulare Arithmetik] (http://www.math.rutgers.edu/~erowland/modulararithmetic.html) und/oder [Abstract (oder elementare) Algebra] (http://www.millersville.edu/~bikenaga/abstract-algebra-1/modular-arithmetic/modular-arithmetic.html). – mctylr

15

Der Titel stellt eine Frage, der Körper eine andere. Um die Titelfrage zu beantworten, wie in C, ist der Operator% ein Ganzzahlmodul, aber es gibt eine Bibliotheksroutine "fmod", die ein Gleitkomma-Modul ist.

use POSIX "fmod"; 

sub foo { 
    my $n1 = shift; 
    my $n2 = shift; 
    print "perl's fmod=" . fmod($n1,$n2), "\n"; 
    my $res = $n1/$n2; 
    my $t = int($res); 
    print "my div=$t", "\n"; 
    $res = $res - $t; 
    $res = $res * $n2; 
    print "my mod=" . $res . "\n\n"; 
} 

foo(3044.952963, 7.1); 
foo(3044.952963, -7.1); 
foo(-3044.952963, 7.1); 
foo(-3044.952963, -7.1); 

gibt

perl's fmod=6.15296300000033 
my div=428 
my mod=6.15296300000033 

perl's fmod=6.15296300000033 
my div=-428 
my mod=6.15296300000033 

perl's fmod=-6.15296300000033 
my div=-428 
my mod=-6.15296300000033 

perl's fmod=-6.15296300000033 
my div=428 
my mod=-6.15296300000033 
+0

fmod, was? Ich stehe korrigiert. Vielen Dank, dass Sie darauf hingewiesen haben. – bugmagnet

+0

Kennt jemand eine Alternative, so dass 'fmod (-23, 10)' '7' anstelle von' -3' zurückgibt? – Flimm

+0

nur 10 hinzufügen, wenn es weniger als 0 ist? – ysth

Verwandte Themen