How to understand place of numbers with Irrational type in Julia?

I recently try to understand how numbers of Irrational type as \pi, e, \gamma (Euler-Mascheroni constant) works in Julia. At these moment I think of them as living in vast space between constants floating points approximation as 3.14 and symbols in symbolic computation (via Mathematica). These is most probably wrong, but this topic is very murky for me.

I search documentation and find little information about Irrational number type (maybe I don’t know which keywords I need to type), so I will be grateful for any materials about them.

Thank to someones post on Discourse I find blog post Some fun with \pi in Julia, which explains many things about inner working of \pi. I wonder why Documentation doesn’t have link to it (maybe I miss that section).

1 Like

There is nothing magical going on, these are just singletons for representing some irrational numbers of special significance that delay or elide the actual computation. Looking at the generic framework and the specific implementation for some of them tells most of the story: eg

==(::Irrational{s}, ::Irrational{s}) where {s} = true
==(::AbstractIrrational, ::AbstractIrrational) = false

so things like

julia> ℯ == π

will happen at compile time, and some identities are encoded, eg

Base.log(::Irrational{:ℯ}) = 1

but otherwise operations will just fall back to conversion to Float64 or the applicable numeric type (if there is one).

The Base docs talk about them briefly, but otherwise I would just treat them as an implementation detail.


The reason why they aren’t just Float64 constants is because Irrationals can be converted to arbitrary precision without loss of precision, but the conversion must be explicit, either by wrapping them in big or by “touching” them with an other arbitrary precision number:

julia> float(pi) # this is a Float64, accurate within precision of a Float64

julia> big(float(pi)) # this converts the Float64 representation to BigFloat: it's inaccurate!

julia> big(pi) # this gives you an accurate value of pi in arbitrary precision

julia> big(1 + pi) # `1 + pi` is a `Float64`, so this will be inaccurate

julia> big(1) + pi # this will be accurate