When is NaN not a number with Python 2.4?

From Wikipedia:

The IEEE Standard for Binary Floating-Point Arithmetic (IEEE 754) is the most widely-used standard for floating-point computation, and is followed by many CPU and FPU implementations.

Included in this specification is the ability to denote intangible numbers such as positive and negative infinity, and NaN (Not a Number). A floating point number is represented either by 32 or 64 bits (depending on how much precision you require). These bits are split up into 3 sections: a fraction, an exponent and a signed bit. More information on the structure of the floating point numbers can be found on Wikipedia.

We use EchoTest against PyAMF to ensure that what is sent to the server is returned verbatim, this way we can check things like data types, references, class mappings etc. We generally use Python 2.5 to run the server but Thijs Triemstra noticed that some numeric tests were failing when using Python 2.4, specifically NaN.

NaN’s are represented by an exponent of 0xff (assuming a 32 bit floating point), and a fraction of non-zero (the signed-bit is, for all intents and purposes of this post, ignored). The bytes sent by the EchoTest are:

00 0000 0000 0001 0004 6563 686F 0003 2F31 ........echo../1 10 3100 0000 0E0A 0000 0001 00FF F800 0000 1..........ÿø... 20 0000 00 ...

Most of the data is related to the AMF request, the important bytes to look at are 0×1b-0×22.

FF F8 00 00 00 00 00 00

We use the Python module struct to read/write data from/to the underlying stream.

import struct bytes = '\xff\xf8\x00\x00\x00\x00\x00\x00' fp = struct.unpack("!d", bytes)[0] print fp

Running this code in Python 2.5, we get: nan

Which is the expected behaviour, but in Python 2.4, we get: -inf

Tested on: Python 2.4.4 (#2, Oct 4 2007, 22:02:31)[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2


blog comments powered by Disqus