I run this in Java 7 and I get:
double remainder1 = 1 % 1000;
double remainder2 = 0.01 % 1000;
double remainder3 = -1 % 1000;
System.out.println("START: "+remainder1+" | "+remainder2+" | "+remainder3);
>>>START: 1.0 | 0.01 | -1.0
But when I run the same operations in Perl 5.8.8 I get different results for two out of three:
my $remainder1 = 1 % 1000;
my $remainder2 = 0.01 % 1000;
my $remainder3 = -1 % 1000;
print "START: $remainder1 | $remainder2 | $remainder3";
>>>START: 1 | 0 | 999
Why is there such a difference in the last two calculations? How can I get perl to match java results?
Modulo or Remainder Operator returns the remainder of the two numbers after division. If you are provided with two numbers, say A and B, A is the dividend and B is the divisor, A mod B is there a remainder of the division of A and B. Modulo operator is an arithmetical operator which is denoted by %.
If both operands for %, the modulus operator have type int, then exprleft % exprright evaluates to the integer remainder. For example, 8 % 3 evaluates to 2 because 8 divided by 3 has a remainder of 2.
If we have negative numbers and use the % operator on them, we will get the result dependent on the left operand's sign. If we have the left operand as positive, we will get the result as positive, and if the left operand is negative, we will get the result as negative.
A modulo-operation is very slow. An if is most likely to be faster than a modulo and more readable.
The second case:
%
operates on integers and floating-point numbers in Java,%
only operates on integers in Perl.The third case:
Java defines the modulus operation such that the following equation is true:
dividend == ((int)(dividend/divisor)) * divisor + (dividend % divisor)
e.g. -1 = 0 * 1000 + -1
Perl defines the modulus operation such that the following equation is true:
$dividend == floor($dividend/$divisor) * divisor + ($dividend % $divisor)
e.g. -1 = -1 * 1000 + 999
The Perl way has the advantage that the quotient (floor($dividend/$divisor)
) will always have the same sign as the dividend.
To get the same behaviour as Java in Perl, use the POSIX::fmod
function.
This is identical to the C function fmod().
$r = fmod($x, $y);
It returns the remainder
$r = $x - $n*$y
, where$n = trunc($x/$y)
. The$r
has the same sign as$x
and magnitude (absolute value) less than the magnitude of$y
.
use POSIX 'fmod';
$m1 = fmod(1, 1000); # 1
$m2 = fmod(0.01, 1000); # 0.01
$m3 = fmod(-1, 1000); # -1
The Java modulo operator can work with floating point types and also has the property that the result will be negative if the first argument is negative.
The Perl modulo operator is for integer types only and the result is always positive.
If you want the Perl one to behave like the Java one, then scale the fractions up to integers with an appropriate multiplication, take the modulus, and then divide to get the final result. Compensate for the negative sign manually. Although you might be better off building your own version of the operator yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With