C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
Be the architects of evolution and help create the mobile internet future. It’s your move---enter to win here!
  #1  
Old April 30th, 2008, 10:26 PM
David_B David_B is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2006
Posts: 39 David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 11 h 43 m 45 sec
Reputation Power: 8
Writing Bulletproof Numerical Programs

Can anybody suggest a website or book that thoroughly covers the topic of writing computer programs to properly deal with computer machine error?

All the books I have on the topic of numerical programming talk about the speed of an algorithm’s convergence, the various algorithms available for a particular application, etc. However, what I would like is material that really gets into the bits and bytes of bulletproof numerical programming.

For example, I would like to write a program to compute the roots of a cubic polynomial equation:

ax^3 + bx^2 + cx + d = 0

A technique for finding the exact roots of this equation is available, but I want to ensure that the program is extremely robust. As a first step, I would like to check if a is zero before dividing the entire equation by a:

x^3 + (b/a)x^2 + (c/a)x + (d/a) = 0

Am I correct in simply doing an if statement?

Code:
if (a == 0)


Should I instead be checking

Code:
if (a == DBL_MIN)


Code:
if (a == DBL_EPSILON)


Or should I be checking against yet some other quantity?

I then proceed to compute various quantities along the way to computing the roots of the original cubic equation. Along the way, what kinds of checks should I be making? Against what quantities should I be comparing my computed values? etc.

These are the sorts of questions I have, but cannot find a good resource to answer them.

I will be going through my program line-by-line to make it as bulletproof as possible. Any help in this goal would be much appreciated.

Reply With Quote
  #2  
Old April 30th, 2008, 11:21 PM
KitKat77's Avatar
KitKat77 KitKat77 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2005
Location: planet<earth_like_t>
Posts: 285 KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 1 Week 18 h 40 m 23 sec
Reputation Power: 53
I don't exactly have pearls of wisdom to offer to you, but I'll link to this paper which has achieved status of canonical work. I attended a talk on it given by this guy, a designer of the Java floating-point library.

Reply With Quote
  #3  
Old April 30th, 2008, 11:24 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,442 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 1 Month 1 h 55 m 33 sec
Reputation Power: 797
There was this book from years ago called Numerical Recipes in C that talked in detail about this. See if you can get your hands on a copy.
__________________
Up the Irons
What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
"Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
Down with Sharon Osbourne

Puzzle of the Month solved by sizeablegrin, etienne141 and L7Sqr, superior C/C++ programmers of the month

Reply With Quote
  #4  
Old May 1st, 2008, 08:54 AM
clifford's Avatar
clifford clifford is offline
Contributing User
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Aug 2003
Location: UK
Posts: 2,413 clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Week 6 Days 6 h 28 m 42 sec
Reputation Power: 320
Neither of your check for zero solutions are good.

A result that is mathematically zero may not be zero in the machine representation because of floating point errors in intermediate calculations.

DBL_MIN is a large magnitude negative number, not zero which is in the centre of the range of double.

DBL_EPSILON is a small positive value. The smallest value that may be added to 1.0 to result in a different stored value. Because it is positive, if anything your conditional should be:
Code:
if( fabs(a) < DBL_EPSILON )
Although in practice I would use a value determined by the necessary precision of the algorithim.

You may not need to worry about it. I just tested these:
Code:
double d = DBL_MAX / DBL_EPSILON ;
Code:
double d = DBL_MAX / 0.0 ;
and neither produce a divide by zero exception, but rather 1.#INF00 (which ia a form of not-a-number or NaN).

So a better approach may be to perform the desired operation and test the result using the _isnan( double ) function. This function is not an ISO standard function but an IEEE recommendation. You will probably find it in float.h or math.h depending on your compiler's library implementation.


Clifford

Last edited by clifford : May 1st, 2008 at 09:40 AM.

Reply With Quote
  #5  
Old May 3rd, 2008, 01:37 PM
David_B David_B is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2006
Posts: 39 David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 11 h 43 m 45 sec
Reputation Power: 8
Thanks for the feedback everyone.

Any other resources to suggest?

I have continued to look around and have been browsing the NETLIB website, which is supposed to be a library of excellent-quality numerical programs. Some of the posted programs use quantities similar to DBL_MIN and DBL_MAX but they use them in ways I wouldn’t expect.

For example, say you want to compute the square of a number, x^2. If x is very small, you want to prevent an underflow error. On the other hand, if x is very large, you want to prevent an overflow error. In these cases, I would expect to compare x^2 with DBL_MIN or DBL_MAX directly. Instead, x^2 is compared to (DBL_MIN/DBL_EPSILON), (DBL_MAX/DBL_EPSILON), the square root of DBL_EPSILON, or some other quantity. Any ideas why this seemingly roundabout approach is taken?

Reply With Quote
  #6  
Old May 5th, 2008, 12:35 PM
KitKat77's Avatar
KitKat77 KitKat77 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2005
Location: planet<earth_like_t>
Posts: 285 KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 1 Week 18 h 40 m 23 sec
Reputation Power: 53
Quote:
Originally Posted by David_B
On the other hand, if x is very large, you want to prevent an overflow error. In these cases, I would expect to compare x^2 with DBL_MIN or DBL_MAX directly. Instead, x^2 is compared to (DBL_MIN/DBL_EPSILON), (DBL_MAX/DBL_EPSILON), [...]


Comparing x^2 with DBL_MAX would really do you no good. If x is too big, x^2 will overflow and will still be smaller than DBL_MAX.

In the realm of integers, it's easier to see. Let's assume that we have only 4 bits to work with and let's assume unsigned integers. INT_MIN is 0 (0000) and INT_MAX is 15 (1111). The square of 5 is 25, or 11001. Oops, overflow and we're left with 1001 (9 in decimal). x^2 (9) is smaller than INT_MAX (15), but we know that's not the right answer so that's not a good validity test.

Now, the realm of floating-points is much more complex and I'm not enough of a math-head to explain what tricks are being performed in them there fancy libraries. I would just trust it (blindly ).

Edit: typo.

Last edited by KitKat77 : May 5th, 2008 at 02:31 PM.

Reply With Quote
  #7  
Old May 5th, 2008, 01:21 PM
sizablegrin's Avatar
sizablegrin sizablegrin is online now
Stubborn ol' L'User
Click here for more information.
 
Join Date: Jun 2005
Posts: 3,070 sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 1 Week 1 Day 16 h 10 m 4 sec
Reputation Power: 1446
The problem is actually worse. The C standard (at least the older one) says that an operation resulting in overflow results in undefined behavior. You might know what your particular compiler does, but you can't write portable, robust code that detects an overflow after the event. You need to detect in advance that it's going to happen.
__________________
C/C++ pointers (Original in the "Commonly Asked Questions" thread).

Reply With Quote
  #8  
Old May 5th, 2008, 02:39 PM
KitKat77's Avatar
KitKat77 KitKat77 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2005
Location: planet<earth_like_t>
Posts: 285 KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level)KitKat77 User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 1 Week 18 h 40 m 23 sec
Reputation Power: 53
Quote:
Originally Posted by sizablegrin
You need to detect in advance that it's going to happen.


As I thought too. But did you notice that the OP claims this library tests the result (x^2) against certain values? Not only that, but they apparently test against DBL_MAX/DBL_EPSILON, which is an obvious overflow itself. I too certainly would like to see that one explained.

David_B: any chance you can point us directly to the source file. I've browsed the netlib website but it's not straightforward.

Reply With Quote
  #9  
Old May 5th, 2008, 09:06 PM
David_B David_B is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2006
Posts: 39 David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level)David_B User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 11 h 43 m 45 sec
Reputation Power: 8
Quote:
Originally Posted by KitKat77
David_B: any chance you can point us directly to the source file. I've browsed the netlib website but it's not straightforward.


Here's a routine from the BLAS library, SNRM2, for computing the Euclidean norm of a real vector.

SNRM2

This routine uses the parameters CUTLO and CUTHI to prevent underflow and overflow, respectively.

CUTLO = maximum of SQRT(U/EPS)
CUTHI = minimum of SQRT(V)

where
EPS = smallest no. such that EPS + 1. .GT. 1.
U = smallest positive no. (underflow limit)
V = largest no. (overflow limit)

I don't know why the square root is taken. In addition, the definitions aren't even the same. Why wouldn't CUTLO simply be SQRT(U) to make its definition analogous to the definition of CUTHI?

In any case, perhaps you could answer one question for me:

When checking a quantity, whether it be user input or computed, against 0, what is the best practice?

Should it use something like CUTLO?
Code:
if (fabs(a) <= (DBL_MIN/DBL_EPSILON))
   take action to deal with zero

Reply With Quote
  #10  
Old May 5th, 2008, 10:09 PM
sizablegrin's Avatar
sizablegrin sizablegrin is online now
Stubborn ol' L'User
Click here for more information.
 
Join Date: Jun 2005
Posts: 3,070 sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 1 Week 1 Day 16 h 10 m 4 sec
Reputation Power: 1446
Quote:
Originally Posted by Clifford
A result that is mathematically zero may not be zero in the machine representation because of floating point errors in intermediate calculations.


Did you read the linked material regarding floating point?

Reply With Quote
  #11  
Old May 6th, 2008, 06:49 AM
clifford's Avatar
clifford clifford is offline
Contributing User
Dev Shed Regular (2000 - 2499 posts)
 
Join Date: Aug 2003
Location: UK
Posts: 2,413 clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level)clifford User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Week 6 Days 6 h 28 m 42 sec
Reputation Power: 320
Quote:
Originally Posted by sizablegrin
Did you read the linked material regarding floating point?
Time and the fact that it is not my problem we are dealing with means that no I did not. Should I have? Presumably there is something wrong about my statement . You may or may not enlighten me, but right now I am not about to wade through that paper right now. I have bookmarked it though!.


Clifford
Comments on this post
sizablegrin agrees: Ahhh. I was addressing the OP and pointing out one of your remarks and the link. I see how that
was misinterpreted, however. Sorry.

Reply With Quote
  #12  
Old May 6th, 2008, 07:11 AM
sizablegrin's Avatar
sizablegrin sizablegrin is online now
Stubborn ol' L'User
Click here for more information.
 
Join Date: Jun 2005
Posts: 3,070 sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 7th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 1 Week 1 Day 16 h 10 m 4 sec
Reputation Power: 1446
See the above comment. Didn't have any points to give .

Reply With Quote