sduser81 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I hit some strange behavior when doing simple comparisons of numbers with leading zeros.

I found that if I don't quote a number I am using for comparison, I sometimes get incorrect result.

Here is my code that demonstrates the issue:

#!/usr/bin/perl -w use strict; my @numbers = qw(022000 022300 022400 022800 023600 024700 024500 0249 +00); foreach my $number(@numbers) { my $compRes1 = $number < 060000; my $compRes2 = $number < '060000'; print "For $number, result1 is $compRes1, result2 is $compRes2\n"; }

Here is the output that I get:
For 022000, result1 is 1, result2 is 1
For 022300, result1 is 1, result2 is 1
For 022400, result1 is 1, result2 is 1
For 022800, result1 is 1, result2 is 1
For 023600, result1 is 1, result2 is 1
For 024700, result1 is , result2 is 1
For 024500, result1 is 1, result2 is 1
For 024900, result1 is , result2 is 1

As can be seen, for '024700' and '024900', result1 is empty while result2 is correct.

I tried this both on 32 and 64 bit Perl, older and newer versions.

I am not sure if this is a problem, just very strange.

Any ideas as to how this can happen are greatly appreciated.


Tim.

Replies are listed 'Best First'.
Re: strange comparison results
by ikegami (Patriarch) on Sep 01, 2010 at 19:01 UTC

    A leading zero in literal indicates the number is octal.

    22000 = 2*105 + 2*104
    022000 = 2*85 + 2*84

    That rule doesn't apply for string numification.

    0+'22000' = 2*105 + 2*104
    0+'022000' = 2*105 + 2*104
    oct('22000') = 2*85 + 2*84
    oct('022000') = 2*85 + 2*84

Re: strange comparison results
by AnomalousMonk (Archbishop) on Sep 01, 2010 at 21:15 UTC

    And just to pound this one completely into the ground: 060000oct == 24576dec.

    Update: And something a bit similar from my own experience:

    >perl -wMstrict -le "my $ubar = 60_0; my $q_ubar = '60_0'; print $ubar; print $q_ubar; print 'unequal' if $ubar != $q_ubar; print 'equal' if 60 == $q_ubar; " 600 60_0 Argument "60_0" isn't numeric in numeric ne (!=) at -e line 1. unequal equal
      Hi,

      Thanks. I should have thought of this myself, as it is so obvious, once it is pointed out.

      Maybe this will help others avoid the same mistake I made.

      Tim