# I will never understand floating-point arithmetic

**URL:** https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342
**Category:** Offtopic
**Tags:** float, precision
**Created:** [March 8, 2024, 10:27am UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342 "2024-03-08T10:27:51Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [March 8, 2024, 10:27am UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/1 "2024-03-08T10:27:51Z")

</div>

I will never understand float point arithmetic…

```julia
julia> a = 10000 * 7 /100
700.0

julia> b = 10000 * 0.07
700.0000000000001

julia> c = 1000 * 0.69999999999999999
700.0

```

(but at list I am aware of the danger…)

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [March 8, 2024, 11:38am UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/2 "2024-03-08T11:38:15Z")

</div>

> [@sylvaticus](#):
>
> (but at list I am aware of the danger…)

As we say in France: “un homme averti en vaut 1.999999999999999”

(Literally, the saying says something like “a forewarned person is worth two”)

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [March 8, 2024, 11:42am UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/3 "2024-03-08T11:42:14Z")

</div>

Also, I’m not sure you were really looking for an explanation, but maybe it will help to note that:

```julia-repl
julia> 7/100
0.07

```

So this is merely an example of non-associativity of the floating-point operations:

```julia-repl
julia> 10000 * (7 / 100)
700.0000000000001

julia> (10000 * 7) / 100
700.0

```

---

<div class="post-metadata">

### Author: ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)
#### Post date: [March 8, 2024, 12:14pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/4 "2024-03-08T12:14:30Z")

</div>

Look at this excellent presentation by Avik Sengupta

> **[Everything You Wanted to Know About Floating Point Numbers, And Didn't Know...](https://juliahub.com/company/resources/webinar/everything-you-wanted/)**
>
> Everything You Wanted to Know About Floating Point Numbers, And Didn't Know Who to Ask - JuliaHub

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [March 8, 2024, 12:25pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/5 "2024-03-08T12:25:17Z")

</div>

> [@ffevotte](#):
>
> ```julia
> julia> 7/100
> 0.07
> 
> ```

Part of the confusion is that, although this is _printed_ as `0.07`, it’s actually a slightly different number. (Binary) floating-point values are **integers times powers of two** , so 7/100 is not exactly representable and has to be rounded to:

```julia
julia> big(7/100)
0.070000000000000006661338147750939242541790008544921875

```

When you realize that a rounding operation has already occurred here, then the fact that multiplying this by `10000` results in something different from `700` is not so surprising. In contrast, when you compute `10000 * 7 / 100` it is parsed as `(10000 * 7) / 100`, and each of _these_ operations can be performed _exactly_ (the result of each operation is an integer value) so there is no rounding (even if you write `1e4 * 7 / 100` so that the first multiplication is done in floating point).

The reason that `7/100` prints as `0.07` is tricky — printing floating-point values in decimal has a long history, and basically all of computer science has coalesced around [the principle](https://dl.acm.org/doi/10.1145/93542.93559) that you should print the _shortest_ decimal number that _rounds to the same value_ when converted back to floating point. (`0.07` will print the same way in Python, C, …)

---

<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: [March 8, 2024, 12:45pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/6 "2024-03-08T12:45:59Z")

</div>

It’s not so hard to understand floating-point arithmetic, actually! Trefethen and Bau’s book “Numerical Linear Algebra” covers the essentials in a couple lectures (each 4 or 5 pages of text). It’ll change your reaction to the above from “Wha…?” to “Yep, that’s how it works, no mystery about it.” Well worth reading.

---

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [March 8, 2024, 1:04pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/7 "2024-03-08T13:04:26Z")

</div>

> [@stevengj](#):
>
> when you compute `10000 * 7 / 100` it is parsed as `(10000 * 7) / 100`, and each of _these_ operations can be performed _exactly_ (the result of each operation is an integer value) so there is no rounding

What is the rule here, is for a / b, when both a and b (or at least b) is an integer (or non-approx), _and the result should be_, then you get exact, i.e. integer?

About “it is parsed as `(10000 \* 7) / 100”, for constants, is it allowed to parse as 7 \* (10000 / 100)"; e.g. if 7 had been not a constant?

---

<div class="post-metadata">

### Author: ![ehgus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ehgus/32/21727_2.png) [@ehgus](https://discourse.julialang.org/u/ehgus)
#### Post date: [March 8, 2024, 1:13pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/9 "2024-03-08T13:13:19Z")

</div>

If you want that calculation, I recommend to use rational number representation:

```Julia
julia> 10000*7//100
700//1

```

---

<div class="post-metadata">

### Author: ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)
#### Post date: [March 8, 2024, 1:17pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/10 "2024-03-08T13:17:53Z")

</div>

To complement a bit, IEEE754 Float64 are stored as M × 2E, where M is the 53-bit integer mantissa and E the 11-bit exponent (some further details omitted).

700.0 becomes M=700 and E=0, as integer values between and  
-2^52 and 2^52-1 are stored with E=0.

0.07 becomes M=6157265115545601 and E=-43, in terms of bits very different from an integer value.

BTW, is there a package for Julia that would reveal mantissa and exponent of IEEE754 floats?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [March 8, 2024, 1:27pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/11 "2024-03-08T13:27:44Z")

</div>

> [@Palli](#):
>
> What is the rule here, is for a / b, when both a and b (or at least b) is an integer (or non-approx), _and the result should be_, then you get exact, i.e. integer?

Yes. The result of each elementary fp operation (`+,-,*,/`) is _as if_ you had done that operation exactly and _then_ rounded to the closest representable value. This means that if the exact result is representable, it will be returned exactly.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [March 8, 2024, 1:30pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/12 "2024-03-08T13:30:37Z")

</div>

> [@stephancb](#):
>
> BTW, is there a package for Julia that would reveal mantissa and exponent of IEEE754 floats?

There are built-in functions: [How to get the significand and the exponent of a floating point number?](https://discourse.julialang.org/t/how-to-get-the-significand-and-the-exponent-of-a-floating-point-number/29900)

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [March 8, 2024, 1:33pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/13 "2024-03-08T13:33:19Z")

</div>

> [@Palli](#):
>
> About “it is parsed as `(10000 \* 7) / 100”, for constants, is it allowed to parse as 7 \* (10000 / 100)"; e.g. if 7 had been not a constant?

No.

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [March 8, 2024, 2:01pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/14 "2024-03-08T14:01:52Z")

</div>

slightly more specifically, no unless you use `@fastmath`

---

<div class="post-metadata">

### Author: ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)
#### Post date: [March 8, 2024, 2:35pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/15 "2024-03-08T14:35:05Z")

</div>

If you dislike this, then try the very nice `DecFP.jl` package, which implements the IEEE 754-2008 decimal floating point standard (`Dec32`, `Dec64`, and `Dec128` types).  
There are some cases dealing with currencies where using decimal floating point may even be required (at least at one point, by EU directive).

As an example, if you are calculating a 5% sales tax on a $0.70 candy bar, if you use binary floating point arithmetic, you get 3 cents, but with decimal arithmetic, it will be 4 cents (and the government will want that extra cent, to be sure, and it can add up!)

---

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [March 8, 2024, 2:50pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/16 "2024-03-08T14:50:52Z")

</div>

…fantastic example…

---

<div class="post-metadata">

### Author: ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)
#### Post date: [March 8, 2024, 3:31pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/17 "2024-03-08T15:31:32Z")

</div>

> [@stephancb](#):
>
> BTW, is there a package for Julia that would reveal mantissa and exponent of IEEE754 floats?

If you’re after visualisation: [`ColorBitstring.jl`](https://github.com/dlfivefifty/ColorBitstring.jl)

 ![](https://global.discourse-cdn.com/julialang/original/3X/3/f/3f37be35e9921b58700bce19ad8e01363da658a9.png)

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [March 8, 2024, 3:34pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/18 "2024-03-08T15:34:23Z")

</div>

> [@Oscar\_Smith](#):
>
> slightly more specifically, no unless you use `@fastmath`

More specifically, fastmath doesn’t change how it is _parsed_, but can allow the compiler to re-associate fp expressions.

---

<div class="post-metadata">

### Author: ![and](https://avatars.discourse-cdn.com/v4/letter/a/2acd7d/32.png) [@and](https://discourse.julialang.org/u/and)
#### Post date: [March 8, 2024, 4:05pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/19 "2024-03-08T16:05:15Z")

</div>

Ha! Please look at my only message on this forum, with three likes by the way! But keep in mind, in fact, I don’t fully understand either, but I hope that when it comes down to it, I’ll turn to this lesson and definitely understand!

> [@Huge computation error in Float32?](https://discourse.julialang.org/t/huge-computation-error-in-float32/106746/12):
>
> Here the topic is explained in a very accessible and gentle manner using Julia: [Fundamentals of Numerical Computation. Floating-point numbers](https://tobydriscoll.net/fnc-julia/intro/floating-point.html)

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [March 8, 2024, 8:26pm UTC](https://discourse.julialang.org/t/i-will-never-understand-floating-point-arithmetic/111342/20 "2024-03-08T20:26:01Z")

</div>

6 posts were split to a new topic: [Avogadro’s number as a floating-point value](https://discourse.julialang.org/t/avogadros-number-as-a-floating-point-value/111379)
