exact_number#

Utilities for using exact representations of real numbers.

This module contains ExactNumber and ExactNumberInput.

ExactNumber’s are used as inputs for components that privacy guarantees depend on. They are used because they can be exactly represented and manipulated using SymPy, which avoids errors such as privacy violations due to numerical imprecision, as well as more mundane user errors from the limitations of floating point arithmetic. See Handling Real Numbers for more information.

ExactNumberInput’s are values which can be automatically converted into ExactNumber’s. They can be any of the following:

Any int or fractions.Fraction:
>>> ExactNumber(5)
5
>>> ExactNumber(-1000000000000000)
-1000000000000000
>>> ExactNumber(Fraction(1, 10))
1/10
>>> ExactNumber(Fraction(127, 128))
127/128
Any sympy.Expr that meets all of the following criteria:

No free symbols

>>> x = sp.symbols("x")
>>> x_plus_1 = x + 1
>>> ExactNumber(x_plus_1)
Traceback (most recent call last):
ValueError: x + 1 contains free symbols
>>> ExactNumber(x_plus_1.subs(x, 3))
4

No undefined functions

>>> f = sp.core.function.Function('f')
>>> ExactNumber(f(2) + 1)
Traceback (most recent call last):
ValueError: f(2) + 1 has an undefined function
>>> f = sp.Lambda(x, x**2)
>>> ExactNumber(f(2) + 1)
5

No floating point values

>>> ExactNumber(sp.Float(3.14))
Traceback (most recent call last):
ValueError: 3.14000000000000 is represented using floating point precision
>>> ExactNumber(sp.Float(3.14) * (sp.Integer(2) ** sp.pi))
Traceback (most recent call last):
ValueError: 3.14*2**pi is invalid: 3.14000000000000 is represented using floating point precision
>>> ExactNumber(sp.Rational("3.14") * (sp.Float(3) ** sp.pi))
Traceback (most recent call last):
ValueError: 157*3.0**pi/50 is invalid: Base of 3.0**pi is invalid: 3.00000000000000 is represented using floating point precision

Is a real number (or +/- infinity)

>>> i = sp.sqrt(sp.Integer(-1))
>>> ExactNumber(i)
Traceback (most recent call last):
ValueError: I has an imaginary component
>>> ExactNumber(1 + 2*i)
Traceback (most recent call last):
ValueError: 1 + 2*I has an imaginary component
>>> ExactNumber(i**2)
-1
>>> ExactNumber(sp.oo)
oo
>>> ExactNumber(-sp.oo)
-oo
>>> ExactNumber(1 + sp.oo*i)
Traceback (most recent call last):
ValueError: 1 + oo*I is invalid: oo*I is invalid: I has an imaginary component
>>> ExactNumber(sp.oo + i)
Traceback (most recent call last):
ValueError: oo + I is invalid: I has an imaginary component
Any str that can be:
  1. Exactly interpreted as a Rational number or

  2. Converted to a valid sympy.Expr by sympy.parsing.sympy_parser.parse_expr()

>>> ExactNumber("0.5")
1/2
>>> ExactNumber("0.123456789")
123456789/1000000000
>>> ExactNumber("2 + 7**2")
51
>>> ExactNumber("2 * pi**2")
2*pi**2
>>> ExactNumber("sqrt(5/3)")
sqrt(15)/3
>>> ExactNumber("pi + I")
Traceback (most recent call last):
ValueError: pi + I has an imaginary component
>>> ExactNumber("x + 1")
Traceback (most recent call last):
ValueError: x + 1 contains free symbols
float(‘inf’) and -float(‘inf’) are allowed:
>>> ExactNumber(float('inf'))
oo
>>> ExactNumber(-float('inf'))
-oo
>>> ExactNumber(3.5)
Traceback (most recent call last):
ValueError: Expected +/-float('inf'), not 3.5

Floating point values typically do not exactly represent the value they are intended to represent, and so are not automatically converted. See tmlt.core.utils.exact_number.from_float for more information.
Finally ExactNumber’s are allowed:
>>> ExactNumber(ExactNumber(3))
3
>>> ExactNumber(ExactNumber("0.5"))
1/2

ExactNumber’s support many common mathematical operations, and can be used in combination with ExactNumberInput’s.

Examples

>>> ExactNumber(1) + ExactNumber("0.5")
3/2
>>> ExactNumber(sp.Integer(7)) - 3
4
>>> ExactNumber(5) ** 2
25
>>> -2 ** ExactNumber(Fraction(1, 2))
-sqrt(2)
>>> 2 / ExactNumber(6)
1/3

Data#

ExactNumberInput#

A type alias for exact representations of real numbers.

See exact_number for more information.

Classes#

ExactNumber

An exact representation of a real number or +/- infinity.

class ExactNumber(value)#

An exact representation of a real number or +/- infinity.

See exact_number for more information and examples.

Methods#

expr()

Returns a sympy.Expr representation.

is_integer()

Returns whether self represents an integer.

is_finite()

Returns whether self represents a finite number.

to_float()

Returns self as a float.

from_float()

Returns an ExactNumber from a float.

__abs__()

Returns absolute value of self.

__neg__()

Returns the additive inverse of self.

__truediv__()

Returns quotient from dividing self by other.

__rtruediv__()

Returns quotient from dividing other by self.

__mul__()

Returns product of self and other.

__add__()

Returns sum of self and other.

__sub__()

Returns difference of self and other.

__rsub__()

Returns difference of other and self.

__pow__()

Returns power obtained by raising self to other.

__rpow__()

Returns power obtained by raising other to self.

__eq__()

Returns True if other and self represent the same value.

__lt__()

Returns True if self is strictly less than other.

__le__()

Returns True if self is less than or equal to other.

__gt__()

Returns True if self is strictly greater than other.

__ge__()

Returns True if self is greater than or equal to other.

Parameters

value (ExactNumberInput) –

__init__(value)#

Constructor.

Parameters

value (ExactNumber | float | int | str | Fraction | ExprUnion[ExactNumber, float, int, str, Fraction, Expr]) – An ExactNumberInput that represents a real number or +/- infinity.

property expr(self)#

Returns a sympy.Expr representation.

Return type

sympy.Expr

property is_integer(self)#

Returns whether self represents an integer.

Return type

bool

property is_finite(self)#

Returns whether self represents a finite number.

Return type

bool

to_float(self, round_up)#

Returns self as a float.

Parameters

round_up (bool) – If True, the returned value is greater than or equal to self. Otherwise, it is less than or equal to self.

Return type

float

static from_float(value, round_up)#

Returns an ExactNumber from a float.

Warning

Floating point values do not have the same algebraic properties as real numbers (For example, operations such as addition and multiplication are not associative or distributive). It is strongly recommended to use exact representations where possible and to only use this method when an exact representation is no longer needed.

Parameters
  • value (float) – A float to convert to an ExactNumber.

  • round_up (bool) – If True, returned value is greater than or equal to value. Otherwise, it is less than or equal to value.

Return type

ExactNumber

__abs__(self)#

Returns absolute value of self.

Return type

ExactNumber

__neg__(self)#

Returns the additive inverse of self.

Return type

ExactNumber

__truediv__(self, other)#

Returns quotient from dividing self by other.

Parameters

other (ExactNumberInput) –

Return type

ExactNumber

__rtruediv__(self, other)#

Returns quotient from dividing other by self.

Parameters

other (ExactNumberInput) –

Return type

ExactNumber

__mul__(self, other)#

Returns product of self and other.

Parameters

other (ExactNumberInput) –

Return type

ExactNumber

__add__(self, other)#

Returns sum of self and other.

Parameters

other (ExactNumberInput) –

Return type

ExactNumber

__sub__(self, other)#

Returns difference of self and other.

Parameters

other (ExactNumberInput) –

Return type

ExactNumber

__rsub__(self, other)#

Returns difference of other and self.

Parameters

other (ExactNumberInput) –

Return type

ExactNumber

__pow__(self, other)#

Returns power obtained by raising self to other.

Parameters

other (ExactNumberInput) –

Return type

ExactNumber

__rpow__(self, other)#

Returns power obtained by raising other to self.

Parameters

other (ExactNumberInput) –

Return type

ExactNumber

__eq__(self, other)#

Returns True if other and self represent the same value.

Parameters

other (Any) –

Return type

bool

__lt__(self, other)#

Returns True if self is strictly less than other.

Parameters

other (Any) –

Return type

bool

__le__(self, other)#

Returns True if self is less than or equal to other.

Parameters

other (Any) –

Return type

bool

__gt__(self, other)#

Returns True if self is strictly greater than other.

Parameters

other (Any) –

Return type

bool

__ge__(self, other)#

Returns True if self is greater than or equal to other.

Parameters

other (Any) –

Return type

bool