perl floating point problem

Discussion in 'Perl Misc' started by info@oliverhallmann.de, Nov 8, 2007.

  1. Guest

    #!/usr/local/bin/perl

    my $i=2.55;
    $i=$i*100;
    print "$i\n";
    my $j=int($i);
    print "$j\n";

    output:
    255
    254

    can someone explain that to me?
     
    , Nov 8, 2007
    #1
    1. Advertising

  2. wrote:
    > #!/usr/local/bin/perl
    >
    > my $i=2.55;
    > $i=$i*100;
    > print "$i\n";
    > my $j=int($i);
    > print "$j\n";
    >
    > output:
    > 255
    > 254
    >
    > can someone explain that to me?


    You must have missed "Basics of Computer Numerics".
    You must also have missed the documentation for int() where it explicitely
    explains this behaviour.
    You could also check 'perldoc -q 999' for a very brief introduction of why
    using floating point numbers has it quirks in Perl, too, just like in any
    other standard programming language.

    jue
     
    Jürgen Exner, Nov 8, 2007
    #2
    1. Advertising

  3. Guest

    On Nov 8, 8:09 am, wrote:
    >
    > #!/usr/local/bin/perl
    > my $i=2.55;
    > $i=$i*100;
    > print "$i\n";
    > my $j=int($i);
    > print "$j\n";
    >
    > output:
    > 255
    > 254
    >
    > can someone explain that to me?



    Basically, you're wondering why:

    if (2.55*100 == 255) {
    print "Equal\n";
    } else {
    print "Not equal\n";
    }

    prints "Not equal" when 2.55 multiplied by 100 can't be anything but
    255.

    This is a behavior common to many languages and platforms, and not
    just Perl. So let me begin by explaining it this way:

    You know how impossible to represent some fractional numbers (such
    as 1/3) in decimal notation? You might consider writing 1/3 as:

    0.333

    or as:

    0.33333333333

    or even:

    0.3333333333333333333333333333333333333

    But the truth is, no matter how many 3s you use, the number you write
    will never fully equal 1/3 (note that this isn't true for 1/2, which
    is easily written as 0.5).

    (Yes, mathematicians will sometimes use a bar over the last 3 to
    denote that it repeats indefinitely, but as far as I know, no computer
    uses this notation.)

    Well, certain numbers cannot be accurately represented in binary
    notation, either. One such number is 2.55, the one you used in your
    script.

    The number 2.5 can be represented in binary notation like this:

    10.1

    (That's 2**1 + 0 + 2**-1.)

    The number 2.625 can be represented in binary notation like this:

    10.101

    (That's 2**1 + 0 + 2**-1 + 0 + 2**-3.)

    But the number 2.55 cannot be accurately represented in binary
    notation. The closest Perl (and many computers) can come up with is:

    10.100011001100110011001100110011001100110011001100110

    (That's 2**1 + 0 + 2**-1 + 0 + 0 + 0 + 2**-5 + 2**-6 + etc.)

    Notice that this number has a repeating part after its decimal
    point (or should I say "binary point"?). Indeed, the "0011" part
    repeats over and over. But your computer doesn't know about the
    repeating part, so this number is as close as it'll get to 2.55
    (which, admittedly, is VERY close). But even though this number is
    very close to 2.55, it's technically still not exactly that.

    Likewise, when you mutiply this number with 100, you get a number
    that's very close to 255, but not quite that value. In fact, the
    value Perl internally creates when you multiply 2.55 with 100 is:

    11111110.111111111111111111111111111111111111111111111

    which is roughly equivalent to 254.9999999999 .

    Here's something fun to try: Try printing out the difference
    between 255 and 2.55*100:

    perl -le "print 255 - 2.55*100"

    This will print out something like:

    2.8421709430404e-014

    The "e-014" part tells us that that's an extremely small number. Yet
    it's still a non-zero number, meaning that Perl thinks that 2.55*100
    is smaller (though not by much) than 255. And since 2.55*100 is
    considered to be smaller than 255, it should now make sense that
    int(2.55*100) returns 254 (instead of 255).

    It just so happens that when we try to print out the value
    2.55*100, it will round to the nearest 0.00000000... "something-place"
    and print out 255, just like it will when running the following Perl
    commands:

    # These both print 255:
    perl -le "print 2.55*100"
    perl -le "print 254.99999999999999"

    The reason it prints out "255" is not because Perl thinks the number
    you passed it is 255, but rather one that rounds to 255 when printed.

    So to Perl, 2.55*100 isn't equivalent to 255 -- it's just that the
    print() statement rounds a value like 254.99999999999999 to 255 before
    printing (since most humans would rather see it rounded to 255 since
    it's so close).

    I hope this explanation helps.

    -- Jean-Luc Romano


    P.S. You can read more about how Perl (and most computers) store
    double precision numbers (and even single precision) in memory by
    looking up "IEEE 754" in Wikipedia. You can jump right to it with
    this link:

    http://en.wikipedia.org/wiki/IEEE_754#Double-precision_64_bit
     
    , Nov 8, 2007
    #3
  4. wrote in news:1194534585.375896.109600
    @k35g2000prh.googlegroups.com:

    > #!/usr/local/bin/perl
    >
    > my $i=2.55;
    > $i=$i*100;
    > print "$i\n";
    > my $j=int($i);
    > print "$j\n";
    >
    > output:
    > 255
    > 254
    >
    > can someone explain that to me?


    perldoc -q 999

    #!/usr/bin/perl

    my $i = 2.55;
    $i = $i * 100;
    printf "%.0f\n", $i;

    __END__

    --
    A. Sinan Unur <>
    (remove .invalid and reverse each component for email address)
    clpmisc guidelines: <URL:http://www.augustmail.com/~tadmc/clpmisc.shtml>
     
    A. Sinan Unur, Nov 8, 2007
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. H aka N
    Replies:
    15
    Views:
    15,691
    Ben Jones
    Mar 2, 2006
  2. Motaz Saad
    Replies:
    7
    Views:
    6,503
  3. Replies:
    4
    Views:
    1,297
    Default User
    Feb 22, 2006
  4. Saraswati lakki
    Replies:
    0
    Views:
    1,356
    Saraswati lakki
    Jan 6, 2012
  5. teeshift
    Replies:
    2
    Views:
    268
    Chris Pearl
    Dec 1, 2006
Loading...

Share This Page