Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Floating Point operations and mistakes

Subject: Floating Point operations and mistakes

From: Roberto Gennari

Date: 25 Jun, 2010 21:45:10

Message: 1 of 6

Hi everyone.
I'm using Matlab since 4 years at my University and this is the first time I post here.
I was programming with Matlab just for solving a puzzle (in particular, looking for three numbers that have tha same product and sum in the interval 0.99-9.99) when I noticed this fact:
the sum of the three floating points number 1.25+1.62+2.8 is correctly 5.670000000000000 (using format long), and the product of the same numbers (in the same order (1.25*1.62*2.8) is 5.670000000000001. The problem is that if you write the product in this order 2.8*1.25*1.62 now you get 5.670000000000000 !!
This happens even with other permutations of the three numbers and it is has been a pain for me because it fails the if control ( actually matlab returns 0 if you ask 1.25+1.62+2.8==1.25*1.62*2.8 but it returns 1 with 1.25+1.62+2.8==2.8*1.25*1.62 !)
Does anybody know why this happens? I have already "solved" the problem rounding the numbers, but I really want to understand why!!

Thank you.

Roberto Gennari
Ferrara, Italy

Subject: Floating Point operations and mistakes

From: dpb

Date: 25 Jun, 2010 21:49:01

Message: 2 of 6

Roberto Gennari wrote:

...[typical floating point query elided for brevity]...

> Does anybody know why this happens? I have already "solved" the problem
> rounding the numbers, but I really want to understand why!!
...

See the question (I forget the number otomh) on floating point in the
Matlab FAQ at

<http://matlabwiki.mathworks.com/MATLAB_FAQ>

Also, for an in-depth tutorial on IEEE floating point, see the Goldberg
paper Appendix available at

<http://docs.sun.com/source/806-3568/ncg_goldberg.html>

All will be explained... :)

--

Subject: Floating Point operations and mistakes

From: Roger Stafford

Date: 25 Jun, 2010 22:37:05

Message: 3 of 6

"Roberto Gennari" <gennari.roberto@gmail.com> wrote in message <i03815$48m$1@fred.mathworks.com>...
> Hi everyone.
> I'm using Matlab since 4 years at my University and this is the first time I post here.
> I was programming with Matlab just for solving a puzzle (in particular, looking for three numbers that have tha same product and sum in the interval 0.99-9.99) when I noticed this fact:
> the sum of the three floating points number 1.25+1.62+2.8 is correctly 5.670000000000000 (using format long), and the product of the same numbers (in the same order (1.25*1.62*2.8) is 5.670000000000001. The problem is that if you write the product in this order 2.8*1.25*1.62 now you get 5.670000000000000 !!
> This happens even with other permutations of the three numbers and it is has been a pain for me because it fails the if control ( actually matlab returns 0 if you ask 1.25+1.62+2.8==1.25*1.62*2.8 but it returns 1 with 1.25+1.62+2.8==2.8*1.25*1.62 !)
> Does anybody know why this happens? I have already "solved" the problem rounding the numbers, but I really want to understand why!!
>
> Thank you.
>
> Roberto Gennari
> Ferrara, Italy
- - - - - - - - - - -
  The numbers 1.25, 1.62, and 2.8 are indeed a solution to your problem. However, matlab uses binary double precision floating point numbers and these are incapable of exactly representing even the second two of those three numbers: 1.62 and 2.8 . Only numbers which are expressible as a fraction with a denominator as a power of two can be exactly represented. For that reason any tests made with their sum and product are unreliable for your purposes. You may overlook valid solutions and you may get apparent solutions that are invalid. You cannot use a binary machine to test exact equalities such as you are attempting to do. It is better to use matlab's symbolic toolbox and deal with exact fractions where you have no worry about round off errors and powers of two.

  As to why the two products came out differently, that is because with the finite precision possible on such numbers, though multiplication with them is commutative, it is not perfectly associative. Here's my favorite counterexample which you can try even on your decimal calculator and I predict it will fail (as well as with matlab):

 3/14 + (3/14 + 15/14) ~= (3/14 + 3/14) + 15/14

Roger Stafford

Subject: Floating Point operations and mistakes

From: James Tursa

Date: 25 Jun, 2010 22:54:05

Message: 4 of 6

"Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in message <i03b2h$hp2$1@fred.mathworks.com>...
>
> The numbers 1.25, 1.62, and 2.8 are indeed a solution to your problem. However, matlab uses binary double precision floating point numbers and these are incapable of exactly representing even the second two of those three numbers: 1.62 and 2.8 . Only numbers which are expressible as a fraction with a denominator as a power of two can be exactly represented. For that reason any tests made with their sum and product are unreliable for your purposes. You may overlook valid solutions and you may get apparent solutions that are invalid. You cannot use a binary machine to test exact equalities such as you are attempting to do.

From what I gathered from the original post, he is only interested in 0.99 - 9.99 in 0.01 increments, so I think his assertion that he can do it with appropriate rounding on the floating point operations is valid, since there is enough precision present in a double to do it. Depends on how he is doing the rounding and comparing.

James Tursa

Subject: Floating Point operations and mistakes

From: James Tursa

Date: 25 Jun, 2010 23:36:21

Message: 5 of 6

"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <i03c2d$l0m$1@fred.mathworks.com>...
> "Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in message <i03b2h$hp2$1@fred.mathworks.com>...
> >
> > The numbers 1.25, 1.62, and 2.8 are indeed a solution to your problem. However, matlab uses binary double precision floating point numbers and these are incapable of exactly representing even the second two of those three numbers: 1.62 and 2.8 . Only numbers which are expressible as a fraction with a denominator as a power of two can be exactly represented. For that reason any tests made with their sum and product are unreliable for your purposes. You may overlook valid solutions and you may get apparent solutions that are invalid. You cannot use a binary machine to test exact equalities such as you are attempting to do.
>
> From what I gathered from the original post, he is only interested in 0.99 - 9.99 in 0.01 increments, so I think his assertion that he can do it with appropriate rounding on the floating point operations is valid, since there is enough precision present in a double to do it. Depends on how he is doing the rounding and comparing.
>
> James Tursa

e.g., brute force doing the raw arithmetic using exact integral values, then dividing by 100 just to print the answer. Works because a double has enough precision to represent all of the results exactly (except of course the printed output).

for k1=1:999
    for k2=k1:999
        for k3=k2:999
            prodk = k1 * k2 * k3;
            sumk = (k1 + k2 + k3) * 10000;
            if( prodk == sumk )
                disp([k1 k2 k3 (k1+k2+k3)]/100);
            end
        end
    end
end

James Tursa

Subject: Floating Point operations and mistakes

From: Roger Stafford

Date: 26 Jun, 2010 01:19:04

Message: 6 of 6

"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <i03ehl$mjj$1@fred.mathworks.com>...
> "James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <i03c2d$l0m$1@fred.mathworks.com>...
> > "Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in message <i03b2h$hp2$1@fred.mathworks.com>...
> > >
> > > The numbers 1.25, 1.62, and 2.8 are indeed a solution to your problem. However, matlab uses binary double precision floating point numbers and these are incapable of exactly representing even the second two of those three numbers: 1.62 and 2.8 . Only numbers which are expressible as a fraction with a denominator as a power of two can be exactly represented. For that reason any tests made with their sum and product are unreliable for your purposes. You may overlook valid solutions and you may get apparent solutions that are invalid. You cannot use a binary machine to test exact equalities such as you are attempting to do.
> >
> > From what I gathered from the original post, he is only interested in 0.99 - 9.99 in 0.01 increments, so I think his assertion that he can do it with appropriate rounding on the floating point operations is valid, since there is enough precision present in a double to do it. Depends on how he is doing the rounding and comparing.
> >
> > James Tursa
>
> e.g., brute force doing the raw arithmetic using exact integral values, then dividing by 100 just to print the answer. Works because a double has enough precision to represent all of the results exactly (except of course the printed output).
>
> for k1=1:999
> for k2=k1:999
> for k3=k2:999
> prodk = k1 * k2 * k3;
> sumk = (k1 + k2 + k3) * 10000;
> if( prodk == sumk )
> disp([k1 k2 k3 (k1+k2+k3)]/100);
> end
> end
> end
> end
>
> James Tursa
- - - - - - - - - - -
  Yes, he could do it that way. In fact he could get more ambitious and generate all combinations of four positive integers, p1, p2, q1, q2, which lie between 1 and some large value N. For each such combination the fraction

 (p1*q2+p2*q1)/(p1*p2-q1*q2),

hopefully reduced to lowest terms, would be a fraction p3/q3 that would be a solution to:

 (p1/q1) + (p2/q2) + (p3/q3) = (p1/q1) * (p2/q2) * (p3/q3)

One could get an endless number of solutions this way.

Roger Stafford

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us