# Poll: speed vs accuracy for \`Float64^-3\`

**URL:** https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619
**Category:** Performance
**Tags:** poll, math, float
**Created:** [March 9, 2022, 7:31am UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619 "2022-03-09T07:31:11Z")
**Posts on this page:** 20
**Page:** 2

<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 9, 2022, 11:59am UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/21 "2022-03-09T11:59:59Z")

</div>

> [@lmiq](#):
>
> all return exactly `0.001` for `10.0^(-3)`

Nitpicking, there is no such thing as “exactly `0.001`” in double (or any) precision IEEE-754, only something whose string representation is exactly `0.001`.

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [March 9, 2022, 1:24pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/22 "2022-03-09T13:24:20Z")

</div>

In Matlab

```julia
>> sprintf('%.20f', 10^-3)

ans =

    '0.00100000000000000002'

```

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [March 9, 2022, 1:38pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/23 "2022-03-09T13:38:31Z")

</div>

Note that this is a different thing, it is the `Int` elevated to the `Int`. Fortran returns `0` in that case.

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [March 9, 2022, 1:40pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/24 "2022-03-09T13:40:06Z")

</div>

To me, `0.0010000000000000002 == 0.001` when I am working with `Float64`. So I don’t view it as “more” or “less” accurate. We all know about the quirks of floating point arithmetic…

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [March 9, 2022, 1:41pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/25 "2022-03-09T13:41:22Z")

</div>

No, it’s not. In Matlab the `ints` are `flints`

```julia
>> class(10)

ans =

    'double'

```

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [March 9, 2022, 1:56pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/26 "2022-03-09T13:56:23Z")

</div>

But I’m confused now

```julia
# Julia 1.8beta
julia> @sprintf("%.20f", 10.0^-3)
"0.00100000000000000024"

# Juila 1.7.0
julia> @sprintf("%.20f", 10.0^-3)
"0.00100000000000000002"

```

---

<div class="post-metadata">

### Author: ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)
#### Post date: [March 9, 2022, 1:57pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/27 "2022-03-09T13:57:56Z")

</div>

Folks, let’s be precise. We are talking about the following binary64 numbers: `0x3F50624DD2F1A9FC` (printed as `0.001`) and `0x3F50624DD2F1A9FD` (printed as `0.0010000000000000002`)

```julia
julia> reinterpret(Float64, 0x3F50624DD2F1A9FC)
0.001

julia> reinterpret(Float64, 0x3F50624DD2F1A9FD)
0.0010000000000000002

```

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [March 9, 2022, 2:03pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/28 "2022-03-09T14:03:58Z")

</div>

Has an analysis been done on how often the approaches actually differ? I tried a few other numbers and it seems that they sometimes give the same result anyway.

---

<div class="post-metadata">

### Author: ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)
#### Post date: [March 9, 2022, 2:17pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/30 "2022-03-09T14:17:11Z")

</div>

The standard IEEE 754-2019 is quite clear on this question, in Subclause 9.2:

> A conforming operation shall return results correctly rounded for the applicable rounding direction for _all_ operands in its domain.

(emphasis added by me)

“Correctly rounded” here means according to the defined rounding mode. All rounding modes (Subclause 4.3) require that

> the floating-point number nearest to the infinitely precise result shall be delivered

Beacuse the true result is actually smaller than `0x3F50624DD2F1A9FC`, the next float (`0x3F50624DD2F1A9FD`) is completely invalid. The true result lies between `0x3F50624DD2F1A9FB` and `0x3F50624DD2F1A9FC`.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [March 9, 2022, 2:22pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/31 "2022-03-09T14:22:03Z")

</div>

There is one digit more than expected there:

```julia
julia> @sprintf("%.20f", 10.0^-3)
"0.00100000000000000002"

julia> reinterpret(Float64, 0x3F50624DD2F1A9FD)
0.0010000000000000002

Matlab:
'0.00100000000000000002'

```

So Matlab is returning the same number other languages return.

---

<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 9, 2022, 2:25pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/32 "2022-03-09T14:25:10Z")

</div>

The accurate approach has average error of .25 ULP, and max error of .5 ULP. The fast approach has average error of .84 ULP, and maximal error of 2 ULP.

---

<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 9, 2022, 2:25pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/33 "2022-03-09T14:25:46Z")

</div>

As such, after more testing, I’m fairly convinced that the slightly slower answer is the one we want.

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [March 9, 2022, 2:26pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/34 "2022-03-09T14:26:24Z")

</div>

I don’t understand how your post actually answers my question about a substantive comparison between the two approaches, but you do seem to suggest that the “less accurate method” is not just less accurate but actually _incorrect_ (according to the standards). If this is indeed true, then we should not even be having this poll. I am not knowledgeable enough on the standards to have that discussion.

> [@josuagrw](#):
>
> Beacuse the true result is actually smaller than `0x3F50624DD2F1A9FC` , the next float ( `0x3F50624DD2F1A9FD` ) is completely invalid. The true result lies between `0x3F50624DD2F1A9FB` and `0x3F50624DD2F1A9FC` .

---

<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 9, 2022, 2:31pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/35 "2022-03-09T14:31:29Z")

</div>

Subclause 9.2 is specifically for correctly rounded functions (what the next version of C++ will call `sqrt_cr`, `exp_cr` etc.) Julia doesn’t guarantee you correct rounding for elementary functions (other than `sqrt`).

---

<div class="post-metadata">

### Author: ![Glen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/glen/32/3583_2.png) [@Glen](https://discourse.julialang.org/u/Glen)
#### Post date: [March 9, 2022, 3:05pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/36 "2022-03-09T15:05:13Z")

</div>

My most common use of x^-3 is in defining SI scaling factors:

```julia
julia> const m = 10^-3
0.0010000000000000002

julia> const u = 10^-6
1.0000000000000004e-6

# ...

```

Then I use `124.2m` etc. in many places. So if the `m` value is less inaccurate then it makes all the other numbers less accurate. The value of `10^-3` is probably in my top 20 of common numbers I use so I really want those to be accurate by default.

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [March 9, 2022, 3:12pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/37 "2022-03-09T15:12:20Z")

</div>

> [@lmiq](#):
>
> So Matlab is returning the same number other languages return.

Matlab and Julia1.7. Not Julia1.8

---

<div class="post-metadata">

### Author: ![Glen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/glen/32/3583_2.png) [@Glen](https://discourse.julialang.org/u/Glen)
#### Post date: [March 9, 2022, 3:13pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/38 "2022-03-09T15:13:46Z")

</div>

Do we have the same issue for other exponents? Using v1.7.2:

```julia
julia> 10^-1 == 0.1
true

julia> 10^-2 == 0.01
false

julia> 10^-3 == 0.001
false

julia> 10^-4 == 0.0001
false

julia> 10^-5 == 0.00001
false

julia> 10^-6 == 0.000001
false

# etc

```

Maybe it is just me being OCD but I feel let down when I get something like `1.0000000000000004e-6`. Maybe I want too much.

Edit: I didn’t realize that this was the case. I thought ops were guaranteed rounding to the right number…from now on I guess I type it out the long way :(. … or just `1e-6` but there is a syntactic beauty with `10^-6`.

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [March 9, 2022, 3:14pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/39 "2022-03-09T15:14:33Z")

</div>

To be fair, if you depend on those constants so much, you should probably be using Unitful.jl (or just typing out `m = 0.001`).

---

<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 9, 2022, 3:18pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/40 "2022-03-09T15:18:10Z")

</div>

In Julia 1.7, literal pow (i.e. `10^-4`) will fairly consistently give an inaccurate answer, but `10.0^-4` would give the correct answer. In 1.8, all negative powers of 10 other than negative 2 and negative 3 currently give the right answer. `10^-2` will likely remain wrong for somewhat complicated reasons, but `10^-3` can be fixed relatively easily.

---

<div class="post-metadata">

### Author: ![Glen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/glen/32/3583_2.png) [@Glen](https://discourse.julialang.org/u/Glen)
#### Post date: [March 9, 2022, 3:30pm UTC](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619/41 "2022-03-09T15:30:04Z")

</div>

Often I just want the SI constants I need (because it pollutes the namespace, taking up single character identifiers) and not actual units.

[Previous page](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619.md?page=1)

[Next page](https://discourse.julialang.org/t/poll-speed-vs-accuracy-for-float64-3/77619.md?page=3)
