Alan
Alan

Reputation: 2178

How do I represent "inf" (floating-point infinity) using the Python C API?

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

Answers (1)

chepner
chepner

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

Related Questions