Numeric Types

Built-in numeric types

There are three numeric types: plain integers (also called integers), long integers, floating point numbers.

Attention

Complex numbers are not supported as built-in types in RPython. However, you can use RPython libraries to handle complex numbers.

This table describes the details of RPython’s built-in types: low-level (LL) types, corresponding C types and sizes in memory (64-bit).

Type

LL Type

C Type

Size (32-bit)

Size (64-bit)

int

Signed

long

32

64

long

Signed

long

32

64

float

Float

double

64

64

For more primitive types, you can find them in the primitive type cheat sheet section.

Note that the int type and long type are same type in RPython, which have same low level representation and size.

All built-in numeric types support the following operations.

def numeric(x, y, f, l):
    print "int: -1024 =", x
    print "float: 3.14 =", f
    print "long: 1L =", l

    print "x + y =", x + y      # sum of x and y
    print "x - y =", x - y      # difference of x and y
    print "x * y =", x * y      # product of x and y
    print "x / y =", x / y      # quotient of x and y
    print "x // y =", x // y    # (floored) quotient of x and y
    print "x % y =", x % y      # remainder of x / y
    print "-x =", -x            # x negated
    print "+x =", +x            # x unchanged

    print "abs(x) =", abs(x)              # absolute value or magnitude of x
    print "int(x) =", int(f)              # x converted to integer
    print "float(x) =", float(y)          # x converted to floating point
    # print "divmod(x, y) =", divmod(x, y)  # the pair (x // y, x % y)
    # print "pow(x, y) =", pow(x, y)        # x to the power y

def entry_point(argv):
    x = -1024    # plain integer
    y = 42
    f = 3.14     # float
    l = 1L       # a long integer
    numeric(x, y, f, l)
    return 0

def target(*args): return entry_point
if __name__ == "__main__": import sys; entry_point(sys.argv)

Attention

Some operations or built-in functions can be used in Python but currently not supported in RPython such as long(), complex(), conjugate(), x ** y, divmode(x, y), pow(x, y) and float(nan). However, RPython’s math library provided some mathematical functions.

Also, it’s worth noting that RPython do constant folding at the compilation time. Therefore, you may found that some built-in functions work with RPython’s code in some scenarios. For example, you can write pow(123, 456) in RPython code and the compiler will calculate the value at the compilation time.

The code snippet shows that although RPython does not support above mentioned built-in functions, it still can do constant folding. For instance, divmod(x, y) will not yield any compilation error if x and y are constants.

def numeric_constfold():
    """Constant folding on numeric."""
    x = -1024
    y = 42

    j = 1j       # yield an imaginary number (complex number with zero real part)
    print "complex: 1j =", j
    print "divmod(x, y) =", divmod(x, y)  # the pair (x // y, x % y)
    print "pow(x, y) =", pow(x, y)        # x to the power y

def numeric_no_constfold(x, y):
    """RPython cannot do constant folding on x and y"""
    print "divmod(x, y) =", divmod(x, y)  # the pair (x // y, x % y)
    print "pow(x, y) =", pow(x, y)        # x to the power y

def entry_point(argv):
    numeric_constfold()
    # numeric_no_constfold(int(argv[1]), int(argv[2]))    # compilation error, comment this function to try constant folding
    return 0

def target(*args): return entry_point
if __name__ == "__main__": import sys; entry_point(sys.argv)

In addition to above functions, the following code illustrated some other unsupported operations in RPython but supported in CPython.

################### UNSUPPORTED IN RPYTHON ######################

def numeric_unsupported():
    """Operations and functions supported in Python but not supported in RPython."""
    x = -1024
    y = 42

    print "long(x) =", long(x)    # x converted to long integer

    re = 1
    im = 2
    # a complex number with real part re, imaginary part im. im defaults to zero.
    print "complex(x) =", complex(re, im)

    c = 0
    # conjugate of the complex number c. (Identity on real numbers)
    print "c.conjugate() =", c.conjugate()

    print "x ** y =", x ** y     # x to the power y

    # float also accepts the strings "nan" and "inf" with an optional prefix
    # "+" or "-" for Not a Number (NaN) and positive or negative infinity.
    print "float(inf) =", float("inf")
    print "float(+inf) =", float("+inf")
    print "float(-inf) =", float("-inf")

    print "float(nan) =", float("nan")
    print "float(+nan) =", float("+nan")
    print "float(-nan) =", float("-nan")

def entry_point(argv):
    numeric_unsupported()
    return 0

def target(*args): return entry_point
if __name__ == "__main__": import sys; entry_point(sys.argv)

Attention

Besides these three built-in numeric types, RPython provides more types such as r_uint, r_int32, r_longlong, etc in the arithmetic module. For more information, please refer to rarithmetic in the rlib section

Not like Python, RPython will not automatically use big integer when appropriate. The big integer type and corresponding operations are provided in the rbigint library, please refer to rbigint in the rlib section.

Bitwise operations

Bitwise operations on integer types in RPython are same as Python.

def numeric_bitwise():
    x = 2
    y = 4
    n = 1

    print "x = ", x, ", y = ", y
    # the bitwise operations sorted in ascending priority
    print "x | y =", x | y      # bitwise or of x and y
    print "x ^ y =", x ^ y      # bitwise exclusive or of x and y
    print "x & y =", x & y      # bitwise and of x and y
    print "x << n =", x << n    # x shifted left by n bits
    print "x >> n =", x >> n    # x shifted right by n bits
    print "~x =", ~x            # the bits of x inverted


def entry_point(argv):
    numeric_bitwise()
    return 0

def target(*args): return entry_point
if __name__ == "__main__": import sys; entry_point(sys.argv)

Additional methods

In Python, there are several additional methods on integer and float types. However, all these methods are not supported in RPython. For example, int.bit_length() and long.bit_length() can be used to get the number of bits to present an integer. Others like float.as_integer_ratio(), float.is_integer(), float.hex(), and float.fronhex(S) are also not supported.

Attention

All additional methods such as int.bit_length() and float.float.as_integer_ratio() on numeric types are not supported in RPython.

Math functions

In Python, the math module provides access to the mathematical functions defined by the C standard. For RPython, you can call math functions in the similar way.

The math functions contain fabs, log, log10, log1p, copysign, atan2, frexp, modf, ldexp, pow, fmod, hypot, floor, sqrt, sin, cos, acos, asin, atan, ceil, cosh, exp, fabs, sinh, tan, tanh, acosh, asinh, atanh, expm1. These math functions will call corresponding C functions in libc.

import math

def numeric_math():
    print math.exp(1e-5) - 1
    print math.pi
    print math.log(10)
    print math.floor(1.5)
    print math.sqrt(2)

def entry_point(argv):
    numeric_math()
    return 0

def target(*args): return entry_point
if __name__ == "__main__": import sys; entry_point(sys.argv)