BigFloat converted to string returns different number?

Hi,

I am new to Julia and in the documentation I came across this:

julia> big"1.23456789012345678901"
1.234567890123456789010000000000000000000000000000000000000000000000000000000004

At first I thought that this is some sort of displaying error but then I tried this:

julia> string(big"1.23456789012345678901")
"1.234567890123456789010000000000000000000000000000000000000000000000000000000004"

How does “1.23456789012345678901” turn into “1.234567890123456789010000000000000000000000000000000000000000000000000000000004”?

I know that normal floats aren’t precise because they can’t be represented exactly but isn’t BigFloat supposed to fix this?

Can someone please explain what is going on here?

Thanks

BigFloat is still a binary format, just with more bits (256 by default). Most decimal expansions have infinite length in binary. If you want to represent decimal numbers exactly, you need to use a different number type.

2 Likes

To slightly elaborate on Oscar’s answer and more directly address the question “what is going on here?”, 1.234567890123456789010000000000000000000000000000000000000000000000000000000004 is the closest arbitrary-precision (well, whatever precision you’re currently using, presumably 256-bit, the default) that can represent the real number 1.23456789012345678901. You can see that both the previous and the following floating-point numbers are much further away from 1.23456789012345678901 than 1.234567890123456789010000000000000000000000000000000000000000000000000000000004 is:

julia> x = big"1.23456789012345678901"
1.234567890123456789010000000000000000000000000000000000000000000000000000000004

julia> prevfloat(x)
1.234567890123456789009999999999999999999999999999999999999999999999999999999987

julia> nextfloat(x)
1.234567890123456789010000000000000000000000000000000000000000000000000000000021
1 Like

To add a simple example to the previous answers: The underlying problem is approximating a decimal fraction in binary terms can be infinite, like this one:
\frac{1}{10} =\frac{1}{16} + \frac{1}{32} + \frac{1}{256} + \frac{1}{512} + \frac{1}{4096} + ...

If you like math, you can even proof that, e.g. if \frac{1}{10} = \frac{n}{2^k} then 2^k = 10n and then 2 | 5.)

Thanks. Then I misunderstood.
I thought it would be an exact decimal representation.
Do you know a different number type in Julia that implements it exactly or should I use rationals instead for calculations and convert the result back into a BigFloat?

1 Like

If you want decimal arithmetic, you should check out GitHub - JuliaMath/Decimals.jl: Pure Julia decimal arithmetic library.. Rational arithmetic also works, but can overflow in some situations.

Thanks.
I didn’t know that prevfloat and nextfloat existed.

Thanks for the example that makes it obvious. But what do you mean with the 2|5?

Ops, “2 | 5” was my notation for “2 divides 5”.