Package: reals
A lightweight python3 library for arithmetic with real numbers.What is Reals?'Reals' is a lightweight Python library for arbitrary precision arithmetic. It allows you to compute approximations to an arbitrary degree of precision, and, contrary to most other libraries,guarantees that all digits it displays are correct. It works by usinginterval arithmeticandcontinued fractions. The bulk of this code is based onBill Gosper's notes on continued fractionsin which he presents algorithms for doing arithmetic on continued fractions.The reals library is characterized by:Correctness; the reals library uses interval arithmetic to ensure that all the digits are correct.Calculations are done in a streaming way; the result of previous calculations can be re-used.Uses no external libraries.Focus on usability.InstallationThe recommended way of installing is usingpip:pip install realsWhy use Reals?With Reals, it is easy to get the result of a numerical calculation: The digits of your results arecorrect, rather than only an approximation like in most other arbitrary-precision libraries.Normally, we expect at least 15 digits of precision from our 64-bit floating-point numbers. For example:>>> from math import pi
>>> print(pi)
3.141592653589793And indeed all of the 16 digits are correct. However, when we do calculations with floats, we will lose a lot of precision, and it is not clear how many digits of the result of a calculations are correct.For example, consider the case where we want to evaluate the first 10 digits of the expression
$$100000 \cdot (22873 \cdot e - 19791 \cdot \pi)$$In native Python, we can use the 64-bit floating-pointfloatdatatype and do$ python
>>> from math import pi, e
>>> print('{:.10f}'.format(100000 * (22873 * e - 19791 * pi)))
5.5148142565However, we might suspect that there would be some floating-point error that crept in this result (and we would be right). So, wepip install mpmathand try again:$ pip install mpmath
$ python
>>> from mpmath import pi, e
>>> 100000 * (22873 * e - 19791 * pi)
mpf('5.5148149840533733')Now, it is not clear how much of these digits are correct. On the other hand, using therealslibrary we do$ pip install reals
$ python
>>> from reals import pi, e
>>> print('{:.10f}'.format(100000 * (22873 * e - 19791 * pi)))
5.5148143686And get only correct digits (note that the last digit might be rounded up). You don't have to take my word from it, you can check the result onWolfram Alpha.Whynotuse Reals?The Reals library does not use the most optimized functions. It places programmer and user convenience above performance. As a rule of thumb, if you need about a couple of hundred digits, you can use Reals, if you need many thousands of digits, you should probably use an arbitrary-precision floating point library such as mpmath (which means you will also need to perform tedious error checking to guarantee that your results are correct).Quick start guideIt is easiest to import any function or number that you need from the reals package:>>> from reals import sqrtNow, you're ready to go:>>> sqrt2 = sqrt(2)
>>> sqrt2
<reals._real.Real object at 0x10d182560 (approximate value: 1.41421)>If you want to see more digits, there are multiple options. Let's say we want 10 digits. Then any of the following would work:>>> sqrt2.evaluate(10)
'1.4142135624'
>>> '{:.10f}'.format(sqrt2)
'1.4142135624'
>>> sqrt2.to_decimal(10)
Decimal('1.4142135624')Currently, the following constants and functions are supported and exported in therealspackage:Constants:pi,e,phiFunctions related to powers:sqrt,exp,logOperators: negation, addition, subtraction, multiplication, division, powersTrigonometric functions:sin,sinh,csc,csch,cos,cosh,sec,sech,tan,tanh,cot,cothDevelopment statusThe library is in pre-1.0 version at the moment. This means it is still under development and can not be considered stable yet.Before the 1.0 release, the following things need to be done:The code needs to be refactored so that there are no cyclic dependenciesMany functions need to be optimizedThe unit test coverage needs to be drastically improvedExamplesPrint10000 digitsof Euler's number $e$:from reals import e

print('{:.10000f}'.format(e))Comparing the first 20 digits ofreals.piandmath.pi:from math import pi as math_pi
from reals import pi as real_pi

print('{:.20f}'.format(math_pi))
print('{:.20f}'.format(real_pi))Get the first10 best rational approximationsto $\pi$:from reals import pi
from reals.approximation import best_rational_approximations

print(best_rational_approximations(pi, 10))Print the floating point number that is closest to $\frac{\pi}{e}$:from reals import pi, e
from reals.approximation import Approximation

print(Approximation(pi / e).closest_float())Print a rational approximation of $e^\pi$ that has an error of less than $10^{-20}$ (again this can be checked withWolfram Alpha):from reals import pi, exp
from reals.approximation import Approximation

from fractions import Fraction


epsilon = Fraction(1, 10**20)

approximation = Approximation(exp(pi))
approximation.improve_epsilon(epsilon)

print(approximation.as_fraction())Calculate a rational interval smaller than $10^{-10}$ that contains $\pi^2 - e^2$:from reals import pi, e
from reals.approximation import Approximation

from fractions import Fraction


epsilon = Fraction(1, 10**10)

approximation = Approximation(pi * pi - e * e)
approximation.improve_epsilon(epsilon)

lower_bound, upper_bound = approximation.interval_fraction()
assert upper_bound - lower_bound < epsilon

print(lower_bound, upper_bound)Continued fractions are not only perfectly amenable to arithmetic, they are
amenable to perfect arithmetic.-- Bill Gosper