[issue3132] implement PEP 3118 struct changes

Meador Inge report at bugs.python.org
Mon Feb 22 05:13:55 CET 2010

Meador Inge <meadori at gmail.com> added the comment:

> The main thing that I realized from this is that unpacking as a ctypes long 
> double isn't all that useful for someone who wants to be able to do arithmetic
> on the unpacked result.  

I agree.  Especially since ctypes 'long double' maps to a Python float and
'.value' would have to be referenced on the ctype 'long double' instance
for doing arithmetic.

> And if you don't want to do arithmetic on the unpacked result, then you're 
> probably just shuffling the bytes around without caring about their meaning,
> so there's no need to unpack as anything other than a sequence of 12 bytes.

One benefit of having a type code for 'long double' (assuming you are mapping
the value to the platform's 'long double') is that the you don't have to know 
how many bytes are in the underlying representation.  As you know, it isn't 
always just 12 bytes.  It depends on the architecture and ABI being used.  Which
from a quick sample, I am seeing can be anywhere from 8 to 16

| Compiler  | Arch     | Bytes            |
| VC++ 8.0  | x86      | 8                |
| VC++ 9.0  | x86      | 8                |
| GCC 4.2.4 | x86      | 12 (default), 16 |
| GCC 4.2.4 | x86-64   | 12, 16 (default) |  
| GCC 4.2.4 | PPC IBM  | 16               |
| GCC 4.2.4 | PPC IEEE | 16               |

> On the other hand, I suppose it's enough to be able to unpack as a ctypes 
> c_longdouble and then convert to a Python float (losing precision) for the 
> arithmetic.  Alternatively, we might consider simply unpacking a long double 
> directly into a Python float (and accepting the loss of precision);
I guess that would be acceptable.  The only thing that I don't like is that
since the transformation is lossy, you can't round trip:

   # this will not hold
   pack('g', unpack('g', byte_str)[0]) == byte_str

> that seems to be what would be most useful for the use-case above.

Which use case?  From the given IRC trace it seems that 'bdesk' was mainly
concerned with (1) pushing bytes around, but (2) thought it "it would be better"
to be able to do arithmetic and thought it would be more useful if it were
not a "black box of 12 bytes".  For use case (1) the loss of precision would 
probably not be acceptable, due to the round trip issue mentioned above.

So using ctypes 'long double' is easier to implement, but is lossy and clunky 
for arithmetic.  Using Python 'float' is easy to implement and easy for 
arithmetic, but is lossy.  Using Decimal is non-lossy and easy for arithmetic, 
but the implementation would be non-trivial and architecture specific 
(unless we just picked a fixed number of bytes regardless of the architecture).


Python tracker <report at bugs.python.org>

More information about the Python-bugs-list mailing list