Bug of <= operator?

H

Haikun

Dear folks,

I'm not sure if this is a bug of the less than "<=" operator, but the
following piece of code looks like a mystery to me.

==== code snippet start =============
#!/usr/bin/perl -w

use strict;
use warnings;

my $start = 0.001;
my $step = 0.001;

for( my $i=$start; $i <= 0.009; $i+=$step){
print "$i\n";
}
==== code snippet end ==============

The output is
0.001
0.002
0.003
0.004
0.005
0.006
0.007
0.008

and 0.009 is missing from the output. If I change "<=" in the for
clause to "le", the output becomes expected.
0.001
0.002
0.003
0.004
0.005
0.006
0.007
0.008
0.009

I know this looks impossible. But if you take a try you'll see it. I'm
using the latest perl 5.8.8 on Windows.

Thanks,
Haikun
 
D

David Squire

Haikun said:
Dear folks,

I'm not sure if this is a bug of the less than "<=" operator, but the
following piece of code looks like a mystery to me.

Time to read the FAQ on the (necessarily approximate) binary floating
point representation of decimal numbers. In Perl or any other language
compiled to run on hardware based on binary representations.

perldoc -q decimal

Regards,

DS
 
J

John W. Krahn

Haikun said:
I'm not sure if this is a bug of the less than "<=" operator, but the
following piece of code looks like a mystery to me.

No, this is not a bug, that is the way that floating point numbers work on
binary computers.


John
 
D

David Squire

David said:
Time to read the FAQ on the (necessarily approximate) binary floating
point representation of decimal numbers. In Perl or any other language
compiled to run on hardware based on binary representations.

perldoc -q decimal

Perhaps this will help to convince:

----

#!/usr/bin/perl
use strict;
use warnings;

my $start = 0.001;
my $step = 0.001;
my $eps = 1e-10;

my $count = 0;
for( my $i=$start; $i <= 0.009 + $eps; $i+=$step){
print "$i\n";
$count++;
print "\$count = $count\n";
}

----

Output:

0.001
$count = 1
0.002
$count = 2
0.003
$count = 3
0.004
$count = 4
0.005
$count = 5
0.006
$count = 6
0.007
$count = 7
0.008
$count = 8
0.009
$count = 9


Regards,

DS
 
H

Haikun

I see. Thanks for the clarification. But then my (possibly irrelevant)
questions is, why would "<=" and "le" exhibit different behavior?

I know "le" is also used to do string comparison. But in this case, if
I code

for( my $i=$start; $i le 9e-03; $i+=$step){
print "$i\n";
}

The output is still correct. I have never observed "le" to fail in this
matter.

Thanks,
Haikun
 
D

David Squire

Haikun wrote:

[top-posting corrected. Please don't do that. See the posting guidelines
for this group]
I see. Thanks for the clarification. But then my (possibly irrelevant)
questions is, why would "<=" and "le" exhibit different behavior?

I know "le" is also used to do string comparison. But in this case, if
I code

for( my $i=$start; $i le 9e-03; $i+=$step){
print "$i\n";
}

The output is still correct. I have never observed "le" to fail in this
matter.

Here's one that does:

----

#!/usr/bin/perl
use strict;
use warnings;

for(my $i = 0; $i le 10; $i++){
print "$i\n";
}

----

Output:

----

0
1

----

Think about the string ordering of the numbers of your example. It works
by coincidence.

DS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top