Python Numbers — Unofficial Python Development (Victor's notes) documentation (original) (raw)

Number Types

Number Tower

The numbers moduleis specified by the PEP 3141 – A Type Hierarchy for Numbers.

Subclasses:

int, float, complex methods and attributes:

int and Fraction attributes:

Conversions in Python

int(obj) and float(obj) accept:

int(obj) rounds towards zero (ROUND_DOWN, ex: int(0.9) == 0 andint(-0.9) == 0).

But int(obj) and float(obj) reject:

complex(obj) accepts:

But complex(obj) rejects:

decimal.Decimal(obj) accepts:

But decimal.Decimal(obj) rejects:

fractions.Fraction(obj) accepts:

But fractions.Fraction(obj) rejects:

int type

Examples:

(123).bit_length() 7 sys.int_info sys.int_info(bits_per_digit=30, sizeof_digit=4)

Serialization as bytes:

(123).to_bytes(4, 'little') b'{\x00\x00\x00' int.from_bytes(b'{\x00\x00\x00', 'little') 123

Rounding:

float type

Examples:

sys.float_info sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1) sys.float_repr_style 'short' (1.2).as_integer_ratio() (5404319552844595, 4503599627370496)

Formatting as hexadecimal (base 16):

(1.1).hex() '0x1.199999999999ap+0' float.fromhex('0x1.199999999999ap+0') 1.1

Rounding:

Fraction

fractions.Fraction(5, 10) # int / int Fraction(1, 2) fractions.Fraction(1.2) # float Fraction(5404319552844595, 4503599627370496)

C API

Convert a Python object to an integer. Type methods:

PyNumber_Long(obj):

PyNumber_Index(x) calls the __index__() method: raises an exception if the type has no __index__() method or if method does not return exactly an int type (*).

_PyLong_FromNbInt(x):

_PyLong_FromNbIndexOrNbInt(x): __index__() or __int__():

PyLong_AsLong() converts a Python int to a C long:

PyLong_AsUnsignedLongMask() converts a Python object to a C unsigned long:

(*) Special case: __int__() or __index__() return a int subclass. This feature is deprecated since Python 3.3 (see commit 6a44f6ee). This feature may be removed from Python 3.9: see bpo-17576.

PyArg_ParseTuple and Py_BuildValue

Reference documentation: Parsing arguments and building values.

PyArg_ParseTuple formats:

Note: In Python 3.7 and older, PyLong_AsLong() only calls __int__(), not __index__().

Script to update this page

number_tower.py:

from future import print_function import numbers import warnings import fractions import decimal

warnings.simplefilter("error", DeprecationWarning)

VALUES = ( ("int", 123), ("float", 1.5), ("complex", complex(0, 1.5)), ("decimal.Decimal", decimal.Decimal("1.1")), ("fractions.Fraction", fractions.Fraction(1, 7)), ("bytes", b"123"), ("str", "123"), )

TYPES = ( ("int", int), ("float", float), ("complex", complex), ("decimal.Decimal", decimal.Decimal), ("fractions.Fraction", fractions.Fraction), )

for type_descr, num_type in TYPES: accepted = [] rejected = [] for value_descr, value in VALUES: try: num_type(value) except TypeError: rejected.append(value_descr) else: accepted.append(value_descr) if accepted: print("%s(obj) accept:" % type_descr) print() for name in accepted: print("* %s" % name) print() if rejected: print("%s(obj) reject:" % type_descr) print() for name in rejected: print("* %s" % name) print() print()

for tower_name, tower_type in ( ("Number", numbers.Number), ("Complex", numbers.Complex), ("Real", numbers.Real), ("Rational", numbers.Rational), ("Integral", numbers.Integral), ): subclasses = [] for type_descr, num_type in TYPES: if issubclass(num_type, tower_type): subclasses.append(type_descr) print("%s subclasses: %s" % (tower_name, ", ".join(subclasses)))