Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations cowski on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems with double format

Status
Not open for further replies.

metalchrist1984

Computer
Sep 4, 2009
4
Hello everybody, I hope somebody can help me.

If I write in the console the following then I get:

>> 3.3-2.2-1.1

ans =

-4.4409e-016

Instead of 0. Situations like that are making some important accuracy errors in my applications. How could I get a 0 using the double format please??

Thank yoy very much, and congratulations for the forum.
 
Replies continue below

Recommended for you

I'm sure there are more elegant ways to do what you want, but here is one thought:

» 3.3-2.2-1.1

ans =

-4.4409e-016

» multiplier = 1e9

multiplier =

1.0000e+009

» (multiplier*3.3-multiplier*2.2-multiplier*1.1)/multiplier

ans =

0


=====================================
Eng-tips forums: The best place on the web for engineering discussions.
 
Thank you very much electricpete. Your solution works, but I prefer a more elegant one, because it is going to be a application to distribute. Thus, the operation that I do where I have that problem is more complex than 3.3-2.2-1.1, although it is the same problem, so if I use your solution the code would be very very more complex, something I am avoiding.

I would like some solution as easy as:

double (3.3)-double (2.2)-double (1.1)=0

But this does not work of course.

Thank you very much.
 
In the other hand my question is: Should I trust in an application that gets this output??:

floor (3.3-2.2-1.1)

ans =

-1

I think it is a basic operation, and it makes it wrong.
 
There are discussions like this at least once a week in the Matlab USENET newsgroup (comp.soft-sys.matlab). There is a FAQ devoted to it:


Simply put, binary fractions (as used by IEEE 754 floating point representation) can't hold multiples of 1/10 (1/100, 1/1000, etc) in an exact way, so there is always a rounding error when working with these numbers. You just can't write code that relies on exact representation unless it's symbolic.

As an aside, most calculators use BCD (Binary coded decimal) which wastes memory by storing each decimal digit in a 4 byte nibble.

- Steve
 
Thank you SomptingGuy,

It seems there is no a basic solution to this problem, so I will try to write my code in a different way, where it could be possible to store the values in different format to double, or using the round () function.

Thank you very much.
 
Sorry to sound negative, but round() won't help you either. You just can't trim those pesky unwanted digits - they come back. You need to change the way you compare values, assuming that's the problem.

if (a==b)

should be replaced by something like

if(abs(a-b)<tol)

where tol is some small number, possibly based on eps if you want to be rigorous.

- Steve
 
Alternatively implement BCD arithmetic in Matlab. I haven't done it, but can't really see it as being difficult, just slow.



Cheers

Greg Locock

SIG:please see FAQ731-376 for tips on how to make the best use of Eng-Tips.
 
Ack!! a four bit nibble. I do have an 'O' level in computer studies.

- Steve
 
How about this (needs symbolic toolbox):
» vpa(3.3)-vpa(2.2)-vpa(1.1)

ans =

0

=====================================
Eng-tips forums: The best place on the web for engineering discussions.
 
Also one has to think about the precision of the numbers that you work with. A 1E-16 error in treating numbers on the order of magnitude of 1 wouldn't be important unless your numbers have 16 significant figures to begin with.


=====================================
Eng-tips forums: The best place on the web for engineering discussions.
 
I can't think of a case where it has come up, but if you were calculating the exponent of something then

x^2

and x^2.0000000000000000000000000000001

have very different properties. That is a quick example, perhaps there are others.

Cheers

Greg Locock

SIG:please see FAQ731-376 for tips on how to make the best use of Eng-Tips.
 
Like I said... "unless your numbers have 16 significant figures to begin with". You are assuming this 2 has 16+ significant figures and if so the unless clause is applicable.

=====================================
Eng-tips forums: The best place on the web for engineering discussions.
 
I was wrong on two counts, #sf, and in fact the example is unhelpful, the difference between the two is tiny.

Cheers

Greg Locock

SIG:please see FAQ731-376 for tips on how to make the best use of Eng-Tips.
 
Fractions cannot be represented exactly in a binary floating point system, unless they are a power of 1/2. While there are problems that thrive on such roundoff errors, most real world problems can get along quite fine.

In your case, if this is a really big deal, then you need to code the problems directly in fractional representations, or use more significant figures, but that just pushes the problem further out in the sig-fig realm. There are various mathmatics applications, like Mathcad, or Mathematica, that can take various exact representations, and produce exact answers.

TTFN

FAQ731-376
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor