# Bug in Julia rational array inplace multiplication

**URL:** <https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446>\
**Category:** General Usage\
**Created:** [April 12, 2020, 12:55pm UTC](https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446 "2020-04-12T12:55:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [April 12, 2020, 12:55pm UTC](https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446/1 "2020-04-12T12:55:52Z")

</div>

On AMD64,

```julia
julia> x=[1//1];x.*=1/5
1-element Array{Rational{Int64},1}:
 3602879701896397//18014398509481984

```

but on i386 works correctly. See [travis build](https://travis-ci.com/github/kagalenko-m-b/RationalDivision/) for this [repo](https://github.com/kagalenko-m-b/RationalDivision/) for behavior on different platforms.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [April 12, 2020, 1:12pm UTC](https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446/2 "2020-04-12T13:12:02Z")

</div>

I’m seeing that answer on all my x64 machines.

Intel/Linux:

```julia
julia> x=[1//1];x.*=1/5
1-element Array{Rational{Int64},1}:
 3602879701896397//18014398509481984

julia> versioninfo()
Julia Version 1.4.0
Commit b8e9a9ecc6 (2020-03-21 16:36 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-3820 CPU @ 3.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-8.0.1 (ORCJIT, sandybridge)

```

Then on an AMD/Windows:

```julia
julia> x=[1//1];x.*=1/5
1-element Array{Rational{Int64},1}:
 3602879701896397//18014398509481984

julia> versioninfo()
Julia Version 1.4.0
Commit b8e9a9ecc6 (2020-03-21 16:36 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: AMD Ryzen Threadripper 1950X 16-Core Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-8.0.1 (ORCJIT, znver1)

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 12, 2020, 1:13pm UTC](https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446/3 "2020-04-12T13:13:39Z")

</div>

It’s not related to in-place multiplication. It’s because `1/5` is not identical to 0.2:

```julia
julia> 1/5 == 1//5
false

julia> big(1/5)
0.200000000000000011102230246251565404236316680908203125

julia> convert(Rational{Int}, 1/5)
3602879701896397//18014398509481984

```

---

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [April 12, 2020, 1:17pm UTC](https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446/4 "2020-04-12T13:17:02Z")

</div>

On any architecture,

```julia
julia> x=[Int32(1)//Int32(1)];x.*=1/5
1-element Array{Rational{Int32},1}:
 1//5

julia> x=[Int64(1)//Int64(1)];x.*=1/5
1-element Array{Rational{Int64},1}:
 3602879701896397//18014398509481984
```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 12, 2020, 1:21pm UTC](https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446/5 "2020-04-12T13:21:17Z")

</div>

To expand on what @DNF said, what’s happening is

```julia
julia> Rational(1//1 * (1/5))
3602879701896397//18014398509481984

```

which happens to be correct (although somewhat unexpected if you are not aware of how floating point works). Cf

> [@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…

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 12, 2020, 1:26pm UTC](https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446/6 "2020-04-12T13:26:00Z")

</div>

> [@Mikhail\_Kagalenko](#):
>
> ```julia
> x=[Int32(1)//Int32(1)];x.*=1/5
> 
> ```

It’s not related to in-place multiplication anyhow:

```julia
julia> Rational{Int32}(0.2)
1//5

julia> Rational{Int64}(0.2)
3602879701896397//18014398509481984

```

Why don’t you simply use rational numbers when multiplying?

```julia
julia> x=[1//1];x.*=1//5
1-element Array{Rational{Int64},1}:
 1//5

```

Relying on conversion of floats to rationals seems pretty brittle.

---

<div class="post-metadata">

**Author:** ![Mikhail\_Kagalenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikhail_kagalenko/32/13257_2.png) [@Mikhail\_Kagalenko](https://discourse.julialang.org/u/Mikhail_Kagalenko)\
**Post date:** [April 12, 2020, 1:41pm UTC](https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446/7 "2020-04-12T13:41:58Z")

</div>

> [@DNF](#):
>
> ```julia
> julia> Rational{Int32}(0.2)
> 1//5
> 
> julia> Rational{Int64}(0.2)
> 3602879701896397//18014398509481984
> 
> ```

I see, thanks for setting me straight.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 12, 2020, 2:16pm UTC](https://discourse.julialang.org/t/bug-in-julia-rational-array-inplace-multiplication/37446/8 "2020-04-12T14:16:02Z")

</div>

Just to nuance it a bit, it is _indirectly_ related to in-place multiplication, because `setindex!` into an `Array{T}` will attempt to convert to `T`:

```julia
julia> a64 = [1//1];

julia> a64[1] = 0.2;

julia> a64
1-element Array{Rational{Int64},1}:
 3602879701896397//18014398509481984

julia> a32 = [Int32(1)//Int32(1)];

julia> a32[1] = 0.2;

julia> a32
1-element Array{Rational{Int32},1}:
 1//5

```

For `Rational{Int32}` there are no values between `0.2` and `1//5`, but for `Rational{Int64}` there _is_.

Amusingly, for `Float32` it’s a different story:

```julia
julia> a32[1] = 0.2f0; # this is a Float32 literal

julia> a32
1-element Array{Rational{Int32},1}:
 13421773//67108864

```

Since `0.2f0` is further away from `1//5` than `0.2` is, `13421773//67108864` is able to sneak in between them.

**Edit:** It actually seems like the rational approximations are exact. I wonder if I understand this correctly:

```julia
julia> big(3602879701896397)/big(18014398509481984)
0.200000000000000011102230246251565404236316680908203125

julia> big(0.2e0)
0.200000000000000011102230246251565404236316680908203125

julia> big(13421773)/big(67108864)
0.20000000298023223876953125

julia> big(0.2f0)
0.20000000298023223876953125

```
