[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Swarm Futures re-cap
From: |
Gary Polhill |
Subject: |
Re: Swarm Futures re-cap |
Date: |
Wed, 16 Oct 2002 15:37:54 +0100 |
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. At the end, the program tells you whether the
result is less than, greater than, or equal to 0.0, using comparison operators,
not printf. The only consistently correct result I get (on a Solaris machine)
is with long double *not* using the L constant modifier! More disturbingly
still, adding 0.4 to a double 0.0 19 times and then subtracting 0.4 19 times
gives a result that is > 0.0, but doing the same 20 times gives a result that
is < 0.0.
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.
Gary
>>> <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.
>
> Gary
--
glen e. p. ropella =><= Hail Eris!
H: 831.335.4950 http://www.ropella.net/~gepr
M: 831.247.7901 http://www.tempusdictum.com
fp-selection.c
Description: Text document