Reputation: 2178
I am writing a Python extension in C/C++ that works with numeric values. When a user passes in a value that is too large to fit into a float, I want to return the value that is represented in Python code as inf
. How can I do that in C/C++? The Floating Point Objects page in the official documentation lists PyFloat_GetMax()
, but nothing for inf
. I searched the Python 3.9 source code for this function and found the following:
SetDblFlag(DBL_MAX);
SetIntFlag(DBL_MAX_EXP);
SetIntFlag(DBL_MAX_10_EXP);
SetDblFlag(DBL_MIN);
SetIntFlag(DBL_MIN_EXP);
SetIntFlag(DBL_MIN_10_EXP);
SetIntFlag(DBL_DIG);
SetIntFlag(DBL_MANT_DIG);
SetDblFlag(DBL_EPSILON);
SetIntFlag(FLT_RADIX);
SetIntFlag(FLT_ROUNDS);
But none of those seems to be what I'm looking for. Theoretically, I could add 1 to DBL_MAX, but that doesn't seem very clean. Any suggestions?
Upvotes: 1
Views: 369
Reputation: 531075
PyFloat_FromDouble
returns a float
object given a double
value. math.h
provides a macro for IEEE 754 infinity (which, FYI, is a float with a 0 significand and all ones in the exponent) which you can use as the argument.
#include <math.h>
...
return PyFloat_FromDouble(INFINITY)
As an aside, you can see this value for infinity in Python itself:
>>> import struct
>>> >>> struct.pack("!f", float('inf'))
b'\x7f\x80\x00\x00'
>>> struct.pack("!d", float('inf'))
b'\x7f\xf0\x00\x00\x00\x00\x00\x00'
In both cases you can see (if you mentally convert hex to binary) the 0 sign bit, the 1 exponent bits, and the 0 signifiant bits. You can also see negative infinity:
>>> struct.pack("!f", -float('inf'))
b'\xff\x80\x00\x00'
>>> struct.pack("!d", -float('inf'))
b'\xff\xf0\x00\x00\x00\x00\x00\x00'
Same as positive infinity, but with the leading 1 sign bit.
Strictly speaking, Python doesn't assume any particular floating-point format; it uses whatever the underlying platform provides. The behavior may be different on systems not using IEEE 754 floating-point values. In particular, I don't know if the presence of INFINITY
(or math.h
itself) is dependent on IEEE 754, or if there is a relevant C standard that mandates it.
Upvotes: 3