Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

perl floating number addition

by adismaug (Acolyte)
on Jul 18, 2009 at 11:54 UTC ( [id://781310]=perlquestion: print w/replies, xml ) Need Help??

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

Dear monks,
I have a script that make a simple math addition.
The strange thing is that it adds some floating point numbers.
The script:
$count = 895.3; while ($count <= 900) { $count += 0.01; print "$count\n"; } The output: 895.31 895.32 895.33 895.34 895.35 895.36 895.37 895.38 895.39 895.4 895.41 895.42 895.43 895.44 895.45 895.46 895.47 895.48 895.49 895.5 895.51 895.52 895.53 895.54 895.55 895.56 895.57 895.58 895.59 895.6 895.61 895.62 895.63 895.64 895.65 895.66 895.67 895.68 895.69 895.7 895.71 895.72 895.73 895.74 895.75 895.76 895.77 895.78 895.79 895.8 895.809999999999 895.819999999999 895.829999999999 895.839999999999 895.849999999999 895.859999999999 895.869999999999 895.879999999999 895.889999999999 895.899999999999 895.909999999999 895.919999999999 895.929999999999 895.939999999999 895.949999999999 895.959999999999 895.969999999999
Your help please. Regards.

Replies are listed 'Best First'.
Humans have too many fingers
by LanX (Saint) on Jul 18, 2009 at 12:22 UTC

    Rule of Thumb:

    To calculate dollars "accurately" with 2 decimal places, you need
    to calculate right from the beginning in cents as integers!

    So just calculate with integers in the desired accuracy and shift the decimal point afterwards²!

    Background:

    Floats are not accurate with decimal fractions because the computer "has only two fingers".

    Experiment

    Just try to express 1/3 accurately in decimal system!

    And now imagine you're an alien with 3 fingers 4 and you have only computers that calculate in decimal fractions¹... wouldn't this annoy you, too?

    Conclusion

    Humans have too many fingers! Downsizing³ to octal system would do it...

    Cheers Rolf

    Footnotes:

      Many modern processors also have support for Binary Coded Decimal (BCD) calculations, including Pentium, Itanium, PA-RISC, IBM mainframes and others. These capabilities can be used with assembly code programming or use of appropriate libraries. Standardization of decimal arithmetic was added to the new IEEE 754 2008 standard.

      So just calculate with integers in the desired accuracy and shift the decimal point afterwards²!

      I agree , that's what I'd do also

Re: perl floating number addition
by FunkyMonk (Chancellor) on Jul 18, 2009 at 12:02 UTC
Re: perl floating number addition
by biohisham (Priest) on Jul 18, 2009 at 12:23 UTC
    it seems like you want to restrict yourself to 2 digits after the point. Hence instead of print,you use "printf or sprintf" functions in the type of notation you want, in this case the "f" for floating numbers preceded by the digit capacity, that is 3 digits before the point and two digits after the point, preceded by %, so it would look like this printf "%6.2f", notice, the point is included in the count hence 6.2 instead of 5.2(Updated after Albannach reply)
    $count = 895.3; while ($count <= 899.99) { $count += 0.01; printf "%6.2f",$count; #(updated) print "\n"; }
    the numbers in computers are approximations and hence comes such issues esp while using higher level programming languages such as Perl.
    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind
      A (pretty common) nit to pick here: the 3 in %3.2f is not the number of digits before the decimal, it's the minimum total width of the resulting field, including the decimal. So if you really want 3 digits, a decimal and 2 digits, then you need %6.2f. This is a minimum and the digits to the left of the decimal will still be printed, so your example of 895.3 still appears to work (even though it would be better described as %5.1f), but try that in a table and you'll find that the column won't line up when another value is just 1.23 for instance.

      For illustration, printf("%3.2f\n",$_) for (3.2,32.2,322.2) gives:

      3.20 32.20 322.20

      while printf("%6.2f\n",$_) for (3.2,32.2,322.2) gives:

      3.20 32.20 322.20

      --
      I'd like to be able to assign to an luser

        Thanks buddy for this, I will have it rectified, when I saw the start of your reply and I was like aoooo I mixed up some other coordinates system from another utility. Thanks, I admit I fell for the trap, I will make an update.
        Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind
Re: perl floating number addition
by poolpi (Hermit) on Jul 20, 2009 at 06:57 UTC

    May be of interest ;)

    #!/usr/bin/perl use strict; use warnings; use Math::BigFloat; my $base = Math::BigFloat->new(q{895.3}); my $incr = Math::BigFloat->new(q{0.01}); while ( $base->bcmp(900) ) { print $base->bstr(), "\n"; $base->badd($incr); }


    hth,
    PooLpi

    'Ebry haffa hoe hab im tik a bush'. Jamaican proverb

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://781310]
Approved by linuxer
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (7)
As of 2024-04-23 16:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found