swarm-modeling
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FP precision problems


From: Joshua O'Madadhain
Subject: FP precision problems
Date: Wed, 16 Oct 2002 12:01:04 -0700 (Pacific Daylight Time)

On Wed, 16 Oct 2002, Gary Polhill wrote:

> I don't think it's just printf, I'm afraid. Try the attached program.
> This takes as argument a number of times to add a constant to 0.0 and
> then subtract it again. I've done it using the same permutations of
> long doubles and L constant modifiers as you, but from my C book
> (Schildt, 1987), which may not be the ultimate authority, long double
> constants take the L modifier, doubles have no modifier, and floats
> get an F. 

K&R 2nd (ANSI) edition essentially agrees with this: 'L' (not 'l') is used
to indicate that a *long* double is desired.  (%g just lets printf()
decide whether to use the %f or %e format depending on how big/small the
value is; they're all straight double formats.)

Not being an Objective C programmer, I don't know how Obj-C might differ
from C in this regard.

Of possible interest are the constants FLT_EPSILON, DBL_EPSILON (and, on
some platforms, LDBL_EPSILON) from float.h; these will tell you the
smallest possible value x such that (1.0 + x != 1.0) for each data type.  
For the record, the value for DBL_EPSILON for Visual C(++) 6.0 is
2.2204460492503131e-016, which is the greatest common factor (if I may
stretch the definition to include FP values) of the values mentioned in
the posting quoted below:  the different answers derived were DBL_EPSILON,
2*DBL_EPSILON, and 3*DBL_EPSILON.

> I think this is a particular issue for agent-based models. I don't
> think we can be the only ABM out there adding or subtracting some
> score to an agent each cycle according to its performance, and then
> doing something to that agent if its score drops below 0.0. The whole
> point of agent-based modelling is that the individual can make a
> difference, so it matters *when* in the simulation the agent has
> something done to it because its score is negative.

<shrug> Well, this is a problem with manipulating finite-precision
floating-point numbers in general.  If the number of different values
you're adding together is small (or at least manageable), then you can
probably finesse this situation to a certain extent by keeping a count for
each separate variable, and multiplying the counts by the values and
summing the results as necessary.  (e.g., 0.4: 23, 0.6: 19, ...)  This
reduces the number of floating-point calculations as much as possible;
every time you perform one, the precision will degrade slightly, so
multiplication is better than repeated addition when you can do it.

Java Swarm programmers may want to make use of java.math.BigDecimal
(Java's arbitrary-precision FP class) if the above suggestions don't work
for them.

Hope this is useful.

Regards,

Joshua O'Madadhain

 address@hidden Per Obscurius...www.ics.uci.edu/~jmadden
  Joshua O'Madadhain: Information Scientist, Musician, Philosopher-At-Tall
 It's that moment of dawning comprehension that I live for--Bill Watterson
My opinions are too rational and insightful to be those of any organization.


> >>> <address@hidden> 15/10/02 19:27:06 >>>
> 
> I think what you're dealing with is the conversion operation of the
> print function.  Since %f assumes a double and %g and %e assume
> long doubles, you're going to run into these problems because it
> scarfs whatever trash happens to surround the thing you're printing.
> 
> Check out the attached program and its results.  Basically, the
> problem is not floating point arithmetic... it's the proper use
> of constants.
> 
> Gary Polhill writes:
>  > Now that I've just found a bug in our model that I've traced back to
>  > floating point arithmetic [e.g. (9 * 0.4) - (6 * 0.6) = 4.44089E-16,
>  > whilst 0.4 + 0.4 + 0.4 + 0.4 + 0.4 + 0.4 + 0.4 + 0.4 + 0.4 - 0.6 - 0.6
>  > - 0.6 - 0.6 - 0.6 - 0.6 = -6.66134E-16 -- not even consistent in which
>  > side of 0 it is... plus, 0.4 + 0.4 + 0.4 - 0.6 + 0.4 - 0.6 + 0.4 + 0.4
>  > + 0.4 + 0.4 + 0.4 - 0.6 - 0.6 - 0.6 - 0.6 = -2.22045E-16, so even the
>  > order matters!], I wonder if one of the standard libraries Swarm
>  > should provide is some kind of proper treatment of floating point
>  > arithmetic, or perhaps even representing numbers as Integer, Rational,
>  > Surd and Real classes somehow. All I know is I'm never trusting
>  > floating points again (these were double "precision", too!).
>  > 
>  > I'd be interested to hear how other people deal with floating
>  > points. Some kind of tolerance windows could be used, but, for example
>  > (0.4 * 50331648.0) - (0.6 * 33554432.0) = 3.72529E-9, so it's not even
>  > immediately obvious what order of magnitude such tolerances should
>  > have! You would also then need to somehow be sure that the smallest
>  > number you could generate given your parameters was always greater
>  > than this tolerance. I am not at all convinced that such certainty can
>  > be obtained, but I do feel sure that others have come across and dealt
>  > with this issue before.





                  ==================================
   Swarm-Modelling is for discussion of Simulation and Modelling techniques
   esp. using Swarm.  For list administration needs (esp. [un]subscribing),
   please send a message to <address@hidden> with "help" in the
   body of the message.
                  ==================================


reply via email to

[Prev in Thread] Current Thread [Next in Thread]