Как вы вычисляете div и mod чисел с плавающей запятой?
В Perl оператор %
, кажется, принимает целые числа. Например:
sub foo {
my $n1 = shift;
my $n2 = shift;
print "perl 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 mod=6
my div=428
my mod=6.15296300000033
perl mod=-1
my div=-428
my mod=6.15296300000033
perl mod=1
my div=-428
my mod=-6.15296300000033
perl mod=-6
my div=428
my mod=-6.15296300000033
Теперь, как вы можете видеть, я придумал "решение" уже для вычисления div
и mod
. Однако я не понимаю, какой эффект должен иметь знак каждого аргумента на результат. Разве div
всегда был бы положительным, будучи числом n2
вписывается в n1
? Как должна работать арифметика в этой ситуации?
Ответы
Ответ 1
Учитывая a = qd + r
, при вычислении остатка для отрицательных значений d
существует неопределенность.
например:.
Выражение −42 ÷ −5
, может быть выражено либо как:
−42 = 9×(−5) + 3
или −42 = 8×(−5) + (−2)
.
Таким образом, остаток равен либо 3, либо -2.
Для получения дополнительной информации: Википедия: Остаток "Неравенство, удовлетворенное остальным"
Кроме того, вывод в случае отрицательных чисел в mod/div зависит от реализации на языках программного обеспечения. См. Википедия: операция Modulo (посмотрите на таблицу справа)
Ответ 2
Название задает один вопрос, тело другое. Чтобы ответить на вопрос заголовка, как и в C, оператор% представляет собой целочисленный модуль, но есть библиотечная подпрограмма "fmod", которая является модулем с плавающей запятой.
use POSIX "fmod";
sub foo {
my $n1 = shift;
my $n2 = shift;
print "perl 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 fmod=6.15296300000033
my div=428
my mod=6.15296300000033
perl fmod=6.15296300000033
my div=-428
my mod=6.15296300000033
perl fmod=-6.15296300000033
my div=-428
my mod=-6.15296300000033
perl fmod=-6.15296300000033
my div=428
my mod=-6.15296300000033