Some numbers (like 6.65) have an exact representation in decimal, but cannot be represented exactly in the binary floating point that computers use (just like 1/3 has no exact decimal representation). As a result, floating point numbers are frequently slightly different than what you would expect. The result of your calculation is not 3, but about 3.000000000000000444.
The traditional way of handling this is to define some small number (called epsilon), and then consider two numbers equal if they differ by less than epsilon.
Your solution of ceil("$n")
works because Perl rounds a floating point number to around 14 decimal places when converting it to a string (thus converting 3.000000000000000444 back to 3). But a faster solution would be to subtract epsilon (since ceil
will round up) before computing ceil
:
my $epsilon = 5e-15; # Or whatever small number you feel is appropriate
my $c = ceil($n - $epsilon);
A floating point subtraction should be faster than converting to a string and back (which involves a lot of division).