# Are BigFloats unable to exactly represent 0.1?

**URL:** <https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192>\
**Category:** General Usage\
**Created:** [June 1, 2021, 1:50pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192 "2021-06-01T13:50:30Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [June 1, 2021, 1:50pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/1 "2021-06-01T13:50:30Z")

</div>

`0.1` is a number that can be exactly represented by a `Float16`, or `Float32`, or a `Float64`.  
(at least according to how we print them)  
But not it would seem (at least according to printing) by a `BigFloat`.

```julia
julia> parse(Float64, "0.1")
0.1

julia> parse(Float32, "0.1")
0.1f0

julia> parse(Float16, "0.1")
Float16(0.1)

julia> parse(BigFloat, "0.1")
0.1000000000000000000000000000000000000000000000000000000000000000000000000000002

```

Is this true? Or is it printing wrong?

(I suspect the answer is going to be insightful about floating point representations and printing being round-trip-able with parsing)

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [June 1, 2021, 1:58pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/2 "2021-06-01T13:58:48Z")

</div>

```julia
julia> 1//10 < 0.1
true

```

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [June 1, 2021, 1:59pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/3 "2021-06-01T13:59:56Z")

</div>

> [@oxinabox](#):
>
> `0.1` is a number that can be exactly represented by a `Float16` , or `Float32` , or a `Float64` .

As Jeffrey pointed out, this assumption is wrong. Another way to see it:

```julia
julia> @printf "%.20f" 0.1f0
0.10000000149011611938
julia> @printf "%.50f" 0.1
0.10000000000000000555111512312578270211815834045410

```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [June 1, 2021, 2:03pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/4 "2021-06-01T14:03:48Z")

</div>

You can also prove by hand that 1/10 is an (infinitely) repeating decimal in base-2, which is why it can’t be represented exactly by binary floating-point with any finite precision: [c# - Are there numbers that are not representable in base 10 but can be represented in base 2? - Software Engineering Stack Exchange](https://softwareengineering.stackexchange.com/a/237018)

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [June 1, 2021, 2:07pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/5 "2021-06-01T14:07:44Z")

</div>

How does the show method know that we want to see 0.1 and not the real value that’s stored?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [June 1, 2021, 2:21pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/6 "2021-06-01T14:21:01Z")

</div>

It’s for the same reason that 0.1 + 0.2 != 0.3 ([https://0.30000000000000004.com](https://0.30000000000000004.com))

> [@roflmaostc](#):
>
> How does the show method know that we want to see 0.1 and not the real value that’s stored?

Julia prints the shortest value that uniquely identifies the float in question when parsed back. The algorithm in question is called “Ryu”, you can find the julia implementation [here](https://github.com/JuliaLang/julia/blob/master/base/ryu/Ryu.jl).

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [June 1, 2021, 3:20pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/7 "2021-06-01T15:20:24Z")

</div>

Is it that we don’t use Ryu for BigFloat but instead use some inferior algorithm?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [June 1, 2021, 3:26pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/8 "2021-06-01T15:26:13Z")

</div>

BigFloat is really a wrapper around the [MPFR](https://www.mpfr.org/) library, which has its own printing algorithm.

---

<div class="post-metadata">

**Author:** ![Jake](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jake/32/46007_2.png) [@Jake](https://discourse.julialang.org/u/Jake)\
**Post date:** [June 1, 2021, 8:41pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/9 "2021-06-01T20:41:38Z")

</div>

And for fun

```julia
julia> bitstring(3)
"0000000000000000000000000000000000000000000000000000000000000011"

julia> bitstring(1.0)
"0011111111110000000000000000000000000000000000000000000000000000"

julia> bitstring(0.1)
"0011111110111001100110011001100110011001100110011001100110011010"

```

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [June 1, 2021, 10:40pm UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/10 "2021-06-01T22:40:48Z")

</div>

BigFloats are binary floating point and it CANNOT exactly represent 0.1 because it is base-2 instead of base-10

---

<div class="post-metadata">

**Author:** ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)\
**Post date:** [June 2, 2021, 8:17am UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/11 "2021-06-02T08:17:45Z")

</div>

I think part of the confusion is that the Julia expression `0.1` _is_ a `Float64` close, but not equal to `1//10`. So `Float64(0.1)` is really the same thing as `0.1`. I try always to be careful to distinguish `0.1` and 1/10 = 0.1 which are different (Julia left and common number right.)

This also implies that `a == 0.30000000000000004` is the correctly rounded answer to the question `0.1 + 0.2 == ?` with rounding error `0.00000000000000002` (and not `0.00000000000000004` as one might think.)

---

<div class="post-metadata">

**Author:** ![waldyrious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/waldyrious/32/80_2.png) [@waldyrious](https://discourse.julialang.org/u/waldyrious)\
**Post date:** [June 2, 2021, 9:14am UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/12 "2021-06-02T09:14:22Z")

</div>

With some [custom pretty-printing on top](https://github.com/JuliaLang/julia/blob/e5884e74a5fb15b11d5e116efa05d186ebe2a74a/base/mpfr.jl#L964-L990).

---

<div class="post-metadata">

**Author:** ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)\
**Post date:** [June 2, 2021, 11:05am UTC](https://discourse.julialang.org/t/are-bigfloats-unable-to-exactly-represent-0-1/62192/13 "2021-06-02T11:05:34Z")

</div>

> [@PSA: floating-point arithmetic](https://discourse.julialang.org/t/psa-floating-point-arithmetic/8678):
>
> Sometimes people are surprised by the results of floating-point calculations such as julia\> 5/6 0.8333333333333334 # shouldn't the last digit be 3? julia\> 2.6 - 0.7 - 1.9 2.220446049250313e-16 # shouldn't the answer be 0? These are not bugs in Julia. They’re consequences of the IEEE-standard 64-bit binary representation of floating-point numbers that is burned into computer hardware, which Julia and many other languages use by default. Brief explanation You can t…
