ctypes' c_longdouble: underflow error (bug?)

kj no.email at please.post
Fri Jul 16 09:53:02 EDT 2010


In <mailman.778.1279213534.1673.python-list at python.org> Thomas Jollans <thomas at jollans.com> writes:

>On 07/15/2010 06:41 PM, kj wrote:
>> In <mailman.733.1279124991.1673.python-list at python.org> Thomas Jollans <thomas at jollans.com> writes:
>> 
>>> http://docs.python.org/library/ctypes.html#fundamental-data-types
>> 
>>> c_longdouble maps to float
>> 
>> Thanks for pointing this out!
>> ~K
>> (Does it make *any difference at all* to use c_longdouble instead
>> of c_double?  If not, I wonder what's the point of having c_longdouble
>> at all.)

>they're still different types (in C).

i understand that doubles and long doubles are different in C.

>on my machine, a double is 64 bits wide, while a long double is 129 bits
>wide. This means that a function that expects a long double argument
>will expect 16 bytes, but ctypes will only pass 8 bytes if you tell it
>to pass double. The same applies to return values.

This is extremely confusing.  From my naive reading of the
documentation, I would have expected that the following two blocks
would produce identical results (expl is one of the standard C math
library exponential functions, with signature "long double expl(long
double)"):

MATH.expl.argtypes = [c_longdouble]
MATH.expl.restype = c_longdouble
print MATH.expl(0)

MATH.expl.argtypes = [c_double]
MATH.expl.restype = c_double
print MATH.expl(0)

...but no, they don't: the first one prints out the correct result,
1.0, while the second one prints out 0.0, of all things.  (In fact,
with the second (mis)configuration, the value returned by MATH.expl
is always equal to its argument, go figure.)

I find these results perplexing because, based on the docs, I
expected that they *both* would be analogous to doing the following
in C:

printf("%f\n", (double) expl((double) 0.0)); /* prints out 1.000000 */

i.e., in *both* cases, expl would get passed a double (which gets
automatically cast into a long double), and in both cases its
returned value would be cast into a double.  Clearly, this is not
what's happening, but I can't figure out the correct interpreation
of what's going on based on the documentation...



More information about the Python-list mailing list