gnugo-devel
[Top][All Lists]
Advanced

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

Re: [gnugo-devel] Floating point arithmetics


From: Paul Pogonyshev
Subject: Re: [gnugo-devel] Floating point arithmetics
Date: Thu, 16 Sep 2004 17:52:52 -0200
User-agent: KMail/1.4.3

nando wrote:

> I rapidly concluded that there must be an underlying problem with the
> connection code. And I strongly suspected floating point arithmetics.
>
> After some debugging, I could spot a location where things could (and
> actually do) go wrong, in the ENQUEUE() macro. The first comparison
> involves values which haven't been normalized, with the consequence that
> the delta, vulnerable1 and vulnerable2 fields might (or might not) get
> overwritten, leading to possible variations in the further processing
> of the queue.
>
> As a possible solution, I rejected the idea of spreading lots of
> gg_normalize_float() calls throughout the code. It seemed much simple
> and efficient to transform the floating point arithmetic into a fixed
> point one (well, sort of). So I wrote a simple patch, just replacing
> float declarations by int ones, and scaling all the constants by 10000
> (smallest constant found in the ENQUEUE_STONE() macro).

As far as I understood (from your description), all distances are
multipliers of 0.0001, but the problem occurs because one distance
can be say 1.0000000000001 and can be 0.999999999999, and so the
comparison may fail or may not.  Can it then be fixed like this:

--- /home/paul/gnugo/engine/readconnect.c       2004-08-26 16:13:15.000000000 
-0200
+++ /tmp/buffer-content-921gzp  2004-09-16 17:50:41.000000000 -0200
@@ -3249,7 +3249,7 @@ pop_connection_heap_entry(struct connect
 
 #define ENQUEUE(conn, from, pos, dist, delta, v1, v2)                  \
   do {                                                                 \
-    if (dist < conn->distances[pos]) {                                 \
+    if (dist + 0.0000001 < conn->distances[pos]) {                     \
       if (conn->distances[pos] == HUGE_CONNECTION_DISTANCE)            \
        conn->queue[conn->queue_end++] = pos;                           \
       conn->distances[pos]   = dist;                                   \

Or am I missing something?

If this works, we can #define some EPSILON constant instead of
hardcored value.

Paul





reply via email to

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