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

Hi guys,
i've got a file which has got loads of numbers ... a lot of them scientific too...like 1e-13, 2e-18 etc...
when i run a numerical sort {$a<=>b}, the scientific numbers don't sort properly. any suggestions on how to fix this?
thanks

Replies are listed 'Best First'.
Re: sorting scientific numbers
by davido (Cardinal) on Jun 08, 2005 at 07:34 UTC

    Chances are good that by virtue of how the numeric data is getting into your script, Perl is seeing '1e-13' as a string, not a number. You can see this happening here:

    perl -e "print q/2e+11/, $/; print 2e+11, $/;"

    You can coerce it back to a number by treating it like one. One way is by adding zero to it:

    perl -e "print q/2e+11/ + 0, $/;"

    And here is that theory applied to an example that may more closely resemble your problem code.

    my @numbers; while( my $num = <DATA> ) { chomp $num; push @numbers, $num + 0; } print "$_\n" for sort { $a <=> $b } @numbers; __DATA__ 1e-13 2e-18 1e-11

    I hope this is on the right track. ;)


    Dave

      That's a good theory, but the spaceship operator $a <=> $b coerces its argument into integers numbers, so this shouldn't matter. Indeed, run your code without the + 0 or simply

      perl -le'$,="\n"; print sort {$a<=>$b} qw(1e-13 2e-18 1e-11)'
      and you will see that the output is the same.

      This is somewhat tangetial, but in a numerical context perl will coerce any string that begins with something recognizable as a number into a number. That's why "0 but true" is a perfectly good1 "true zero." See Is '2x' + '3y' == 5 documented? and the man page for the C atof function.

      1Well, not quite. As it turns out '0 but true' has a "special dispensation" that disables the warnings that perl would have otherwise have generated. E.g.:
      % perl -wle 'print "OK" if "0 but true" < 1' OK % perl -wle 'print "OK" if "0 but righteous" < 1' Argument "0 but righteous" isn't numeric in numeric lt (<) at -e line +1. OK

      the lowliest monk

Re: sorting scientific numbers
by salva (Canon) on Jun 08, 2005 at 10:47 UTC
    did you meant ... ?
    sort {$a<=>$b} ^--- $ here
    I supposse this is not the problem, but your OP doesn't contain enough information: post your code!
Re: sorting scientific numbers
by ysth (Canon) on Jun 08, 2005 at 07:31 UTC
    This works for me. Can you show an example that's not working for you?
      sorry for the late reply guys. You know what, it does work if i just manually feed it into the array. WIll have to see why its not sorting when i pick it up from the data file. I'll post some sample data and the code tonite, if it still doesn't work.
      sorted out the problem...it was a problem in the file. thanks a lot guys.
Re: sorting scientific numbers
by trammell (Priest) on Jun 08, 2005 at 19:11 UTC
    Here's some code that does the right thing for me:
    #!perl -l $, = ' '; my @n = qw/ 1e-13 2e-14 3e-15 4e-16 /; print sort @n; print sort { $a <=> $b } @n; @n = (1e-13, 2e-14, 3e-15, 4e-16); print sort @n; print sort { $a <=> $b } @n; __END__ 1e-13 2e-14 3e-15 4e-16 4e-16 3e-15 2e-14 1e-13 1e-13 2e-14 3e-15 4e-16 4e-16 3e-15 2e-14 1e-13