On AMD64,

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

but on i386 works correctly. See travis build for this repo for behavior on different platforms.

On AMD64,

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

but on i386 works correctly. See travis build for this repo for behavior on different platforms.

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

Intel/Linux:

```
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> 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)
```

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

is not identical to 0.2:

```
julia> 1/5 == 1//5
false
julia> big(1/5)
0.200000000000000011102230246251565404236316680908203125
julia> convert(Rational{Int}, 1/5)
3602879701896397//18014398509481984
```

3 Likes

On any architecture,

```
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
```

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

```
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

1 Like

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

```
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> x=[1//1];x.*=1//5
1-element Array{Rational{Int64},1}:
1//5
```

Relying on conversion of floats to rationals seems pretty brittle.

1 Like

I see, thanks for setting me straight.

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> 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> 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> 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
```