Как вы рассчитываете div и мод чисел с плавающей точкой? - PullRequest
11 голосов
/ 30 января 2009

В Perl оператор %, кажется, принимает целые числа. Например:

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

дает

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

Теперь, как вы можете видеть, у меня уже есть «решение» для вычисления div и mod. Однако я не понимаю, какое влияние должен иметь знак каждого аргумента на результат. Не будет ли div всегда положительным, если число n2 вписывается в n1? Как должна работать арифметика в этой ситуации?

Ответы [ 2 ]

15 голосов
/ 01 февраля 2009

Заголовок задает один вопрос, тело - другой. Чтобы ответить на вопрос заголовка, как и в C, оператор% является целочисленным модулем, но есть библиотечная подпрограмма "fmod", которая является модулем с плавающей запятой.

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

дает

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
8 голосов
/ 30 января 2009

Учитывая a = qd + r, существует неопределенность при расчете остатка для отрицательных значений d.

например:.

Выражение −42 ÷ −5, может быть выражено как: −42 = 9×(−5) + 3 или −42 = 8×(−5) + (−2).

Таким образом, остаток равен либо 3, либо -2.

Для получения дополнительной информации: Википедия: Остаток "Неравенство, удовлетворяемое остатком"

Кроме того, вывод в случае отрицательных чисел в mod / div зависит от реализации на языках программного обеспечения. См. Википедия: Операция по модулю (посмотрите на таблицу справа)

...