http://www.perlmonks.org?node_id=1098544

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

$a=5.10; $c=10.10; $b=$a*100; $d=$c*100; printf("%d\n",$b); printf("%u\n",$d);

This gives me the output 509 and 1010. However when I just use print and log the values I get 510 and 1010. Why is there a difference when I use %d and %ld in case of printf/sprintf?

Replies are listed 'Best First'.
Re: Different values while applying format specifiers
by kennethk (Abbot) on Aug 25, 2014 at 18:46 UTC
Re: Different values while applying format specifiers
by toolic (Bishop) on Aug 25, 2014 at 18:05 UTC
    You didn't post your sprintf code. Can you create a small testcase which we can run which demonstrates your problem?
    use warnings; use strict; $a=5.10; $b=$a*100; printf("%d\n",$b); my $x=sprintf("%d\n",$b); print $x; __END__ 509 509
Re: Different values while applying format specifiers
by Anonymous Monk on Aug 25, 2014 at 18:47 UTC
Re: Different values while applying format specifiers
by perlmonksuser (Initiate) on Aug 26, 2014 at 20:25 UTC
    Thank you all for the insights. But why does it have to work for 10.1, 3.1 and not 5.1, 4.1
    printf("%d\n",100 * 3.1); print "10.1 Manipulation\n"; printf("%d\n",100 * 10.1); $c=sprintf("%d\n",100 * 10.1); printf("%.0f\n",100 * 10.1); print $c; print "5.1 Manipulation\n"; printf("%d\n",100 * 5.1); $d=sprintf("%d\n",100 * 5.1); printf("%.0f\n",100 * 5.1); print $d;
    This is the output that I see for the above code
    310 10.1 Manipulation 1010 1010 1010 5.1 Manipulation 509 510 509
      To explore what the numbers actually look like in memory, print them out with unrealistic precision:
      printf "%.16f\n", 5.1 * 100; printf "%.16f\n", 10.1 * 100; printf "%.16f\n", 20.1 * 100;
      And read that link.

      #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Decimal 5.1 is an endless repeating binary number in IEEE-754 format and therefore the value in the memory represents 5.09999999999 in decimal. Accordingly decimal 3.1 is not an endless binary float in the memory.
      Just to word pme's response a little more simply: Some decimal numbers can be represented by IEEE-754 exactly, others cannot. For lots more information see the article linked above, or search the Wikipedia page Floating point for the term "exact".