[Verse-dev] About NAN and various REAL_MAX

Emil Brink emil at obsession.se
Wed Sep 13 10:04:12 CEST 2006


Hello.

Since the discussion seems to have died out, and Eskil asked me the other
day when we should put together the official R6 release (which very likely
will be r6p1, there are some fixes that happened post-SIGGRAPH), I'm posting
something new about this dear old subject. :)

The issue(s), for those who need a reminder. This is the way I look at 
things, and how I remember various discussions (here, and on IRC (#verse on
Freenode.net, do join us)), and I might misremember stuff so I will be care-
ful when it comes to representing the opinions of others.

* Verse has portability problems due to the V_REAL32_MAX and V_REAL64_MAX
   constants defined in verse.h, since the literal floats in there are not
   acceptable on all platforms.

* These constants are used *both* by the internal netpacking layer to signal
   that a parameter or field is not used, which might turn a create-command
   into a delete, or similar, _and_ by various application-level code (such
   as the reference server and Eskil's applications) to mark for instance a
   vertex location in an array as being free.

* Eskil feels the latter is a valid use of the constants, that it's a useful
   service provided by the Verse API. At least, this is my impression from
   our talks on the subject.

My solution is two-pronged:

* Replace use of a magical float value for internal netpacking purposes,
   with the use of a *more* magic float value, namely a NAN. NANs are meant
   to signal "this is not a number", which fits very well with what we want
   to achieve. This can be done totally inside Verse, i.e. not visible in
   verse.h at all. This makes sense, since the use of NAN to mean things on
   a network binary level is somethingn the API user should not be aware of.

   We will add documentation stating that it is not legal to hand Verse a
   NAN value for e.g. a vertex location, and that doing so can change the
   meaning of the command sent. This should not be a serious restriction.

* If we want to preserve the application level service of having Verse-
   prefixed constants for large floating point values, we can simply add
   an #include <float.h> and alias V_REAL32/64_MAX to FLT_MAX/DLB_MAX,
   respectively. Personally I feel this is outside what the Verse API is
   supposed to be doing, and would much rather just have applications to
   this on their own. It's easy enough. I'm not sure if it creates problems
   that, with this change in place, it will be possible to set a vertex to
   every valid float value, though. Perhaps for that reason it would be good
   to expose the MARK stuff (below), in which case we would need to document
   it even more clearly.

There, that's about it, I think. I've done the above changes to my local
tree, but haven't checked anything in. For the curious, the relevant NAN-
handling looks like this (no comments included, yet):

In v_network.h:

typedef union {
	unsigned int	uint32;
	float	real32;
} VRealMarker;

extern VRealMarker	VMARK;

#define	V_REAL_MARK		VMARK.real32
#define	V_REAL_IS_MARK(x)	((*(uint32 *) &x) == VMARK.uint32)

with the corresponding implementation in v_network.c:

VRealMarker VMARK = { 0xffffffff };

This uses the all-ones binary pattern to encode NAN, which is a valid one
according to my tests, and <http://en.wikipedia.org/wiki/NaN>. This is a
"quiet nan", which I'm not certain is optimal. I picked the pattern mainly
because it's simple, and symmetric with respect to endianness.

Again, note that this code is *not* visible to users of the Verse API, so
application programmers do not need to care about the fact that you can't
compare for MARK directly, but must use the provided macro (which, by the
way, does not call isnan() since isnan() is C99 according to my man pages).

The total diff, without the auto-generated code, to implement this on the
reference server is about 60 lines, which I consider very small.

I would very much prefer a r6p1 which has this silly issue resolved, since
there are currently people (Blender) mirroring the Verse code, and that have
been running into the compilation issues since they build on more platforms
and compilers than we do.

Comments, please.

Regards,

/Emil



More information about the Verse-dev mailing list