incorrect simple floating point math
-
- Posts: 36
- Joined: Mon May 04, 2009 5:19 pm
incorrect simple floating point math
I am using Lisp-in-a-box (Clisp) and it is a hit and miss kind of thing with doing simple math. Sometimes I would get the correct answer and other times I get odd results. Here are a few examples of what I actually typed:
Correct:
(+ 2 2.4 5.1)
9.5
Wrong:
(+ 2 4.2 8.4)
14.599999
Any idea what is going on?
Correct:
(+ 2 2.4 5.1)
9.5
Wrong:
(+ 2 4.2 8.4)
14.599999
Any idea what is going on?
Re: incorrect simple floating point math
There is nothing incorrect in the examples you posted. Please review the following links.
Wikipedia
http://en.wikipedia.org/wiki/Floating_point
"What Every Computer Scientist Should Know About Floating-Point Arithmetic"
http://docs.sun.com/source/806-3568/ncg_goldberg.html
~ Tom
Wikipedia
http://en.wikipedia.org/wiki/Floating_point
"What Every Computer Scientist Should Know About Floating-Point Arithmetic"
http://docs.sun.com/source/806-3568/ncg_goldberg.html
~ Tom
Thomas M. Hermann
Odonata Research LLC
http://www.odonata-research.com/
http://www.linkedin.com/in/thomasmhermann
Odonata Research LLC
http://www.odonata-research.com/
http://www.linkedin.com/in/thomasmhermann
Re: incorrect simple floating point math
If these kinds of floating point errors are actually a problem, you have the option of avoiding floating point all together. You could use rational number arithmetic.speech impediment wrote:I get odd results
Code: Select all
(+ 2 12/5 51/10)
(+ 2 46/5 42/5)
Code: Select all
(apply #'+ (mapcar #'rationalize '(2 2.4 5.1)))
-
- Posts: 36
- Joined: Mon May 04, 2009 5:19 pm
Re: incorrect simple floating point math
Wow... is this how most programmers program mathematically when using numbers with decimal points? If not, how does one generally program with mathematical accuracy? I've been reading links for a while and it seems like there isn't an easy solution to doing accurate math. Maybe Vedic Mathematics?If these kinds of floating point errors are actually a problem, you have the option of avoiding floating point all together. You could use rational number arithmetic.

Re: incorrect simple floating point math
Financial calculations are performed using decimal (base10) as opposed to binary (base 2) arithmetic. In decimal arithmetic, your examples would give the same results you learned in school. In binary arithmetic, there are no exact representations for 1/5, 1/25, 1/125, etc.; thus you see "errors" in the calculation.
Most decimal calculations are done using "binary coded decimal", where each 4 binary bits (0-15) is used to store one decimal digit (0-9).
Surprisingly, a bit of searching around didn't turn up any decimal arithmetic libraries for CL. If someone wanted to write one, I would recommend that they start by reading the docs on the following page.
http://speleotrove.com/decimal/
Most decimal calculations are done using "binary coded decimal", where each 4 binary bits (0-15) is used to store one decimal digit (0-9).
Surprisingly, a bit of searching around didn't turn up any decimal arithmetic libraries for CL. If someone wanted to write one, I would recommend that they start by reading the docs on the following page.
http://speleotrove.com/decimal/
-
- Posts: 447
- Joined: Sat Jun 28, 2008 7:49 am
- Location: Austin, TX
- Contact:
Re: incorrect simple floating point math
Most programmers just get it wrong.speech impediment wrote:Wow... is this how most programmers program mathematically when using numbers with decimal points? If not, how does one generally program with mathematical accuracy? I've been reading links for a while and it seems like there isn't an easy solution to doing accurate math. Maybe Vedic Mathematics?If these kinds of floating point errors are actually a problem, you have the option of avoiding floating point all together. You could use rational number arithmetic.
The ones who really care about numerical results have scars to prove it.
Cheers, Dave
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/
-
- Posts: 406
- Joined: Sat Mar 07, 2009 6:17 pm
- Location: Brazil
- Contact:
Re: incorrect simple floating point math
If you want "mathematical accuracy" then you need rational numbers. Any floating point arithmetic will need to round numbers (and this will inevitably make the sum operation not associative). The decimal base is no less of an issue than binary base (there is no way represent 1/3 or 2/3 in a finite decimal number, but in base 3 this is an easy task). The difference in this problem is that you are providing simple decimal numbers and converting them to binary representation.speech impediment wrote:Wow... is this how most programmers program mathematically when using numbers with decimal points? If not, how does one generally program with mathematical accuracy? I've been reading links for a while and it seems like there isn't an easy solution to doing accurate math. Maybe Vedic Mathematics?
I also faced this problem once, when I made a simple money change calculator - you provide an amount of money and it returns how many and which coins you should use to pay. For instance:
(exchange 0.64) =>
1 coin of 50 cents
1 coin of 10 cents
4 coins of 1 cent
The solution I came up with was to multiply the number by 100 and round it before calculating the amount of coins.
Re: incorrect simple floating point math
Floating point numbers are extremely useful, but in order to get sensible results you need to know what they are and what you are doing.Wow... is this how most programmers program mathematically when using numbers with decimal points? If not, how does one generally program with mathematical accuracy? I've been reading links for a while and it seems like there isn't an easy solution to doing accurate math. Maybe Vedic Mathematics?
People have noted things like BCD and other techniques, but the thing you have to realize is that there is no single "right" answer to the fundamental problem that you can't represent an arbitrary real number to full precision in a computer.
BCD works well because the fractional part is of known magnitude.
Basically, floating point numbers are rational approximations to real numbers that a) have a fixed precision and b) are logarithmically distributed over a large range of magnitudes. This is extremely useful but as you've already found out, if you just treat them as real numbers you'll run into grief easily.
Re: incorrect simple floating point math
Since someone mentioned financial calculations: Never do financial calculations with floats!
Floats are just a representation for non-integer, non-rational measurements. Their accuracy is, of course, limited by the number of places after the point. A base 2 float with x places after the point naturally has less precision than a base 10 float with x places. If you are converting a base 2 float with 10 places to base 10, then anything after the first 3 places of the result cannot be actual information coming from the base 2 float.
If you have precise fractions, don't use floats. The simplest way in Common Lisp is to use rationals, and convert input with RATIONALIZE and output for display with FLOAT. For fixed-point arithmetic (like financials), just using integers as multiples of the lowest unit (e.g. cents) is also a good way.
Floats are just a representation for non-integer, non-rational measurements. Their accuracy is, of course, limited by the number of places after the point. A base 2 float with x places after the point naturally has less precision than a base 10 float with x places. If you are converting a base 2 float with 10 places to base 10, then anything after the first 3 places of the result cannot be actual information coming from the base 2 float.
If you have precise fractions, don't use floats. The simplest way in Common Lisp is to use rationals, and convert input with RATIONALIZE and output for display with FLOAT. For fixed-point arithmetic (like financials), just using integers as multiples of the lowest unit (e.g. cents) is also a good way.
"Just throw more hardware at it" is the root of all evil.
Svante
Svante
-
- Posts: 447
- Joined: Sat Jun 28, 2008 7:49 am
- Location: Austin, TX
- Contact:
Re: incorrect simple floating point math
Interestingly, old HP calculators used to use a form of "floating point BCD" (my term, not HP's), if I remember correctly. Each number was stored internally as a significand, represented in BCD, and an exponent, just like an IEEE float, but for the change of representation of the significand. It was sort of a best-of-both worlds technique that allowed the calculators to avoid many of the binary representation hiccups that have been discussed in this thread, but still gave them a large range for calculations. If you're seriously interested in numerical work, studying these old calculators is really eye opening. They were remarkably well-engineered. I honestly wish I still had my old HP-15C. It was the best calculator I ever owned and only died sometime in the middle of college, circa 1988.nuntius wrote:Most decimal calculations are done using "binary coded decimal", where each 4 binary bits (0-15) is used to store one decimal digit (0-9).
Surprisingly, a bit of searching around didn't turn up any decimal arithmetic libraries for CL. If someone wanted to write one, I would recommend that they start by reading the docs on the following page.
http://speleotrove.com/decimal/

Cheers, Dave
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/