2009-01-30 7 views
11

En Perl, el operador % parece asumir números enteros. Por ejemplo:¿Cómo se calcula div y mod de números de coma flotante?

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); 

da

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 

Ahora bien, como se puede ver, yo he llegado con una "solución" para el cálculo ya div y mod. Sin embargo, lo que no entiendo es qué efecto debe tener el signo de cada argumento sobre el resultado. ¿No sería positivo el div, siendo la cantidad de veces n2 que cabe en n1? ¿Cómo se supone que la aritmética funciona en esta situación?

Respuesta

8

Dado a = qd + r, hay una ambigüedad al calcular el resto para los valores negativos de d.

ej .:

La expresión −42 ÷ −5, se puede expresar como, ya sea como: −42 = 9×(−5) + 3 o −42 = 8×(−5) + (−2).

El resto es entonces 3 o -2.

Para más información: Wikipedia:Remainder "Inequality satisfied by the remainder"

Además, la salida en el caso de los números negativos en mod/div depende de la implementación en lenguajes de software. Consulte Wikipedia: Modulo operation (consulte la tabla de la derecha)

+0

Para la formación matemática, véase [aritmética modular] (http://www.math.rutgers.edu/~erowland/modulararithmetic.html) y/o [resumen (o elemental) álgebra] (http://www.millersville.edu/~bikenaga/abstract-algebra-1/modular-arithmetic/modular-arithmetic.html). – mctylr

15

El título hace una pregunta, el cuerpo es otra. Para responder la pregunta del título, al igual que en C, el operador% es un módulo entero, pero hay una rutina de biblioteca "fmod" que es un módulo de coma flotante.

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); 

da

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, eh? Estoy corregido. Muchas gracias por señalar eso. – bugmagnet

+0

¿Alguien sabe de una alternativa como 'fmod (-23, 10)' devuelve '7' en lugar de' -3'? – Flimm

+0

acaba de agregar 10 si es menor que 0? – ysth

Cuestiones relacionadas