perlmathfloating-pointdivisionmodulo

How do you calculate div and mod of floating point numbers?


In Perl, the % operator seems to assume integers. For instance:

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

gives

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

Now as you can see, I've come up with a "solution" already for calculating div and mod. However, what I don't understand is what effect the sign of each argument should have on the result. Wouldn't the div always be positive, being the number of times n2 fits into n1? How's the arithmetic supposed to work in this situation?


Solution

  • Given a = qd + r, there is an ambiguity when calculating the remainder for negative values of d.

    E.g.:

    The expression −42 ÷ −5, can be expressed as either as: −42 = 9×(−5) + 3 or −42 = 8×(−5) + (−2).

    So the remainder is then either 3 or −2.

    For more info: Wikipedia:Remainder "Inequality satisfied by the remainder"

    Also, the output in case of negative numbers in mod / div is implementation dependent in software languages. See Wikipedia: Modulo operation (look at the table on right)