Is 230 % 5 == 4? Sometimes it is.

I don't want to give this away in this post, but see if you can suss out this problem:

 my $value = 200 * 1.15;      # 230
 print "Value is [$value]\n";   # Value is [230]
 my $result = $value % 5;     # 4

When you give up, read my answer on O'Reilly Answers.


The actual value of $value isn't integer 230 but a floating point number like 229.99. Stringification rounds off the $value slightly (is that documented anywhere?). The modulus operator is an integer operator and thus converts $value to the integer 229 (I wouldn't mind that giving a warning), hence the result 4.

Lesson of the day: don't mix floating points and integer operations.

Output in Perl 6: 0.

The reason is that 1.25 is represented as a rational number with integer numerator and denominator, so the identity 200 * 1.15 == 230 actually holds.

Put another way:
15:47 <@pmichaud> I'd simply say that Perl 6 knows how to represent 1.15 exactly. :-)

There's a whole field of study called Numerical Analysis that deals with problems like this. Or as a colleague of mine once said: 1 + 1 = 3, with rounding.

Leave a comment

About brian d foy

user-pic I'm the author of Mastering Perl, and the co-author of Learning Perl (6th Edition), Intermediate Perl, Programming Perl (4th Edition) and Effective Perl Programming (2nd Edition).