By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,222 Members | 2,416 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,222 IT Pros & Developers. It's quick & easy.

struct doesn't handle NaN values?

P: n/a
Perhaps I'm doing something wrong: the struct module docs say
it's IEE 754, but I can't figure out how to get it to handle
NaN values correctly (either packing or unpacking).
x = float('nan')
struct.pack("<f",x) Traceback (most recent call last):
File "<stdin>", line 1, in ?
SystemError: frexp() result out of range
struct.unpack("<f",'\xff\xff\xff\xff')

(-6.8056469327705772e+38,)

I don't have my copy of 754 at hand, but I'm pretty sure that
0xffffffff is a NaN (printf on IA32 Linux agrees) and not
-6.8056469327705772e+38 as claimed by struct.unpack().

--
Grant Edwards grante Yow! Of course, you
at UNDERSTAND about the PLAIDS
visi.com in the SPIN CYCLE --
Jul 18 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
"Grant Edwards" <gr****@visi.com> wrote in message
news:sl*******************@grante.rivatek.com...
Perhaps I'm doing something wrong: the struct module docs say
it's IEE 754, but I can't figure out how to get it to handle
NaN values correctly (either packing or unpacking).
x = float('nan')
struct.pack("<f",x) Traceback (most recent call last):
File "<stdin>", line 1, in ?
SystemError: frexp() result out of range
struct.unpack("<f",'\xff\xff\xff\xff')
(-6.8056469327705772e+38,)

I don't have my copy of 754 at hand, but I'm pretty sure that
0xffffffff is a NaN (printf on IA32 Linux agrees) and not
-6.8056469327705772e+38 as claimed by struct.unpack().


I believe that struct uses the c library as is, like the
float support in general. Unfortunately, that leaves
everyone at the mercy of the rather inconsistent
and ideosyncratic implementations of corner cases
in existing c libraries. See PEP 754 for a discussion
of the issues.

John Roth
--
Grant Edwards grante Yow! Of course, you
at UNDERSTAND about the PLAIDS visi.com in the SPIN CYCLE --

Jul 18 '05 #2

P: n/a
At some point, Grant Edwards <gr****@visi.com> wrote:
Perhaps I'm doing something wrong: the struct module docs say
it's IEE 754, but I can't figure out how to get it to handle
NaN values correctly (either packing or unpacking).
x = float('nan')
struct.pack("<f",x) Traceback (most recent call last):
File "<stdin>", line 1, in ?
SystemError: frexp() result out of range


Doing this with the native format is no trouble:
struct.pack('f', x) '\x00\x00\xc0\x7f'

....which is a NaN since the exponent part is all 1's and the
significand is non-zero.
struct.unpack("<f",'\xff\xff\xff\xff') (-6.8056469327705772e+38,)


Again,
struct.unpack('f', '\xff\xff\xff\xff')

(nan,)

Of course, if you want to worry about endian issues here, I think
you're SOL with using struct.

--
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca
Jul 18 '05 #3

P: n/a
On 2004-05-13, John Roth <ne********@jhrothjr.com> wrote:
Perhaps I'm doing something wrong: the struct module docs say
it's IEE 754, but I can't figure out how to get it to handle
NaN values correctly (either packing or unpacking).
I believe that struct uses the c library as is,
That's not what the docs say. The struct docs says it converts
between native Python values and IEEE 754. If that's not the
case and it converts between Python float format and "native C
library" format, then the docs need to be changed [and I'll
need to write something that converts to/from IEEE 754 format.]
like the float support in general. Unfortunately, that leaves
everyone at the mercy of the rather inconsistent and
ideosyncratic implementations of corner cases in existing c
libraries.


But, my c library seems to handle it correctly:

1) 0xffffffff is treated correctly as a NaN.
2) NaN's are detected and converted to strings as 'nan'.

Which part of the C library is broken?

--
Grant Edwards grante Yow! AIEEEEE! I am having
at an UNDULATING EXPERIENCE!
visi.com
Jul 18 '05 #4

P: n/a
On 2004-05-13, David M. Cooke <co**********@physics.mcmaster.ca> wrote:
Perhaps I'm doing something wrong: the struct module docs say
it's IEE 754, but I can't figure out how to get it to handle
NaN values correctly (either packing or unpacking).
Doing this with the native format is no trouble: Of course, if you want to worry about endian issues here, I think
you're SOL with using struct.


Yes, I want to worry about endian issues. I'm communicating
via DeviceNet, and DeviceNet specifies little-endian. I don't
want to assume the host is little-endian, so I guess I'm SOL. :(

OTOH, I suppose if I assume that 32-bit integers and floats
have the same byte order, I can use 32-bit native integers as
an intermediate format:

nanString = struct.pack("f",float('nan'))
nanInt, = struct.unpack("I",nanString)
extNan = struct.pack("<I",nanInt)

That's ugly, and I'm sure will break someday, but I guess it
works for now.

I suppose I should take a look at the sources for struct and
see if I can fix it...

--
Grant Edwards grante Yow! How's it going in
at those MODULAR LOVE UNITS??
visi.com
Jul 18 '05 #5

P: n/a

"Grant Edwards" <gr****@visi.com> wrote in message
news:sl*******************@grante.rivatek.com...
On 2004-05-13, John Roth <ne********@jhrothjr.com> wrote:
Perhaps I'm doing something wrong: the struct module docs say
it's IEE 754, but I can't figure out how to get it to handle
NaN values correctly (either packing or unpacking).
I believe that struct uses the c library as is,


That's not what the docs say. The struct docs says it converts
between native Python values and IEEE 754. If that's not the
case and it converts between Python float format and "native C
library" format, then the docs need to be changed [and I'll
need to write something that converts to/from IEEE 754 format.]


Actually, it doesn't. It does say IEEE, but it doesn't say
IEEE 754. While that's a nit, it also doesn't say it converts
anything other than byte order. When you look at the source,
I suspect that what you'll find is a straight copy from the buffer
into wherever the float object keeps the actual value, or the
reverse, of course.
like the float support in general. Unfortunately, that leaves
everyone at the mercy of the rather inconsistent and
ideosyncratic implementations of corner cases in existing c
libraries.
But, my c library seems to handle it correctly:

1) 0xffffffff is treated correctly as a NaN.
2) NaN's are detected and converted to strings as 'nan'.

Which part of the C library is broken?


Which C library? Python runs on 20 different systems,
many of which have multiple operating systems, each
of which has its own C library with its own problems.
It's not even a standards issue: the older standards didn't
specify what the C library's conversion routines should do.

I referred you to PEP 754 for a reason. That PEP contains
a thorough discussion of the issues in the treatment of special
values in Python floating point.

http://www.python.org/peps/pep-0754.html

It also contains a reference to a module that handles
the matter.
John Roth
--
Grant Edwards grante Yow! AIEEEEE! I am having at an UNDULATING EXPERIENCE! visi.com

Jul 18 '05 #6

P: n/a
On 2004-05-13, John Roth <ne********@jhrothjr.com> wrote:
Which part of the C library is broken?
Which C library?


That's what I'm asked? I was told the C library was broken. I
wanted to know what C library.
Python runs on 20 different systems, many of which have
multiple operating systems, each of which has its own C
library with its own problems. It's not even a standards
issue: the older standards didn't specify what the C library's
conversion routines should do.
I presumed that struct was doing the conversion itself. The
doc specified IEEE format, it would have to do it's own
conversion since it couldn't assume that the host used IEEE
format, and as you say, there's no portable library support
that can be relied upon.
I referred you to PEP 754 for a reason. That PEP contains
a thorough discussion of the issues in the treatment of special
values in Python floating point.

http://www.python.org/peps/pep-0754.html

It also contains a reference to a module that handles
the matter.


I read it. It only handles double-precision values, and I'm
working with single-precision values.

--
Grant Edwards grante Yow! I just had my entire
at INTESTINAL TRACT coated
visi.com with TEFLON!
Jul 18 '05 #7

P: n/a

"Grant Edwards" <gr****@visi.com> wrote in message
news:sl*******************@grante.rivatek.com...
On 2004-05-13, John Roth <ne********@jhrothjr.com> wrote:
Which part of the C library is broken?
Which C library?


That's what I'm asked? I was told the C library was broken. I
wanted to know what C library.


The breakage has to do with the character values they
use to denote infinities and NaN, not (as far as
I know) with the detection of them. Whether they are
"broken" is a matter of interpretation, since the C standard
didn't specify what the library should expect and return
when converting from string to float and vice versa.
What is true is that they aren't consistent.
Python runs on 20 different systems, many of which have
multiple operating systems, each of which has its own C
library with its own problems. It's not even a standards
issue: the older standards didn't specify what the C library's
conversion routines should do.
I presumed that struct was doing the conversion itself. The
doc specified IEEE format, it would have to do it's own
conversion since it couldn't assume that the host used IEEE
format, and as you say, there's no portable library support
that can be relied upon.


I don't think so. I believe that the reference to IEEE means
that it generally expects bit compatible IEEE representations.
There may be differences, but I doubt if struct is aware of
them. As usual, the source would be definitive.
I referred you to PEP 754 for a reason. That PEP contains
a thorough discussion of the issues in the treatment of special
values in Python floating point.

http://www.python.org/peps/pep-0754.html

It also contains a reference to a module that handles
the matter.


I read it. It only handles double-precision values, and I'm
working with single-precision values.


I expect it would be easy enough to convert. I just read
it, and it doesn't look at all complicated.

John Roth


--
Grant Edwards grante Yow! I just had my entire at INTESTINAL TRACT coated
visi.com with TEFLON!

Jul 18 '05 #8

P: n/a
In article <10*************@news.supernews.com>, John Roth wrote:
Which part of the C library is broken?

Which C library?
That's what I'm askeing? I was told the C library was broken.
I wanted to know what C library.


The breakage has to do with the character values they use to
denote infinities and NaN,


Right. That's got nothing to do with what I'm currently
whining about, which was struct's failure when byte ordering is
specified to convert properly between a native NaN and IEEE 754
NaN (even when native format is IEEE 754) . I'm quite happy
with the way string<->native-float handles NaNs on the host I'm
using. Not that it wouldn't be nice for it to be consistent
across platforms.
not (as far as I know) with the detection of them. Whether
they are "broken" is a matter of interpretation, since the C
standard didn't specify what the library should expect and
return when converting from string to float and vice versa.
What is true is that they aren't consistent.
Though I realize there are consistency issues, they work quite
well enough for my application at the moment. Struct, however,
doesn't.
I presumed that struct was doing the conversion itself. The
doc specified IEEE format, it would have to do it's own
conversion since it couldn't assume that the host used IEEE
format, and as you say, there's no portable library support
that can be relied upon.


I don't think so.


Eh? So you think that struct is using a C library to do the
conversion, or that there is portable C library support for
converting between native FP format and IEEE 754?
I believe that the reference to IEEE means that it generally
expects bit compatible IEEE representations.
Hmm, what would be the difference would be between standrd IEEE
representation and a "bit-compatible IEEE representation".
There may be differences, but I doubt if struct is aware of
them. As usual, the source would be definitive.
It also contains a reference to a module that handles the
matter.


I read it. It only handles double-precision values, and I'm
working with single-precision values.


I expect it would be easy enough to convert. I just read it,
and it doesn't look at all complicated.


Probably not. I've done it before (in C) but having struct
convert the values properly would be right thing to do rather
expect the user to check for certain values that struct doesn't
convert correctly.

--
Grant Edwards grante Yow! My LESLIE GORE record
at is BROKEN...
visi.com
Jul 18 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.