Vector conversion mixed rational integers

Yes, I am quite familiar with mathematical questions. But naively I thought that in julia it was done differently and I tried to do something like you suggest.
But I tried with a monster like Vector {Union {Rational, Int}}[ ] that julia didn’t digest :laughing:

Fyi, there is this past post from the boss that might still be valid.

1 Like

You were near!

@show Union{Real,Int}[0, 1//2, 1, 3//2, 4//2]
@show Union{Rational,Int}[0, 1//2, 1, 3//2, 4//2]

yields

Union{Real, Int}[0, 1 // 2, 1, 3 // 2, 4 // 2] = Real[0, 1//2, 1, 3//2, 2//1]
Union{Rational, Int}[0, 1 // 2, 1, 3 // 2, 4 // 2] = Union{Int64, Rational}[0, 1//2, 1, 3//2, 2//1]
1 Like

That is a very good point from Stefan. But, yet, I kinda expected an AbstractRational which Integer inherits, but the concrete Rational only is defined after Int is defined. The conventionally identified with this subset, they are not the same as this subset still holds however.

To stay at the problem Y, why ther are two differente types of rational?

julia> Rational{Int}===Rational
false

What is the meaning of the first type (Rational {Int})?

to return to problem X anhoter function to get nice Xticks


siwp(n,d)=if isinteger(n//d) string(Int(n/d)) else string(n,"/",d) end

Instead of converting floats, it is better to use proper integer division: div(n, d) or n÷d.

3 Likes

Some reasonably different types of rational

julia> Rational !- Rational{Int}, Rational{Int} != Rational{BigInt}
(true, true)

julia> typeof(Rational(1, 2)), typeof(Rational(big"1", big"2"))
(Rational{Int64}, Rational{BigInt})

julia> sizeof(Rational(1, 2)), sizeof(Rational(Int16(1), Int16(2)))
(16, 4)

julia> typeof(Rational), Rational.body
UnionAll, Rational{T<:Integer}
1 Like

This is the definition of Rational:

"""
    Rational{T<:Integer} <: Real

Rational number type, with numerator and denominator of type `T`.
Rationals are checked for overflow.
"""
struct Rational{T<:Integer} <: Real
    num::T
    den::T

    # Unexported inner constructor of Rational that bypasses all checks
    global unsafe_rational(::Type{T}, num, den) where {T} = new{T}(num, den)
end

So, Rational{Int} stores the numerator and denominator as Int, while Rational{BigInt} (for example) uses BigInt (and it is therefore an “infinite” precision rational).

1 Like

I think the whole tread is related to the issue of the default printing of Rationals which is not I think the best possible. I proposed https://github.com/JuliaLang/julia/issues/42626
which was rather well received but no action followed…

1 Like

out of curiosity I made these tests:

julia> 3//true
3//1

julia> false//5
0//1

julia> typeof(false//5)
Rational{Int64}

The type of the numerator and the denominator needs to be the same. So it gets automatically converted to the largest between the two. You can, however, do:

julia> false // true
false//true

julia> typeof(false // true)
Rational{Bool}

true and false are integer (sub)types and when mixed with Int64 get converted to Int64 and:

false//5 == 0//5 == 0//1     # Rational{Int64}

If instead we mix Bool with UInt8 integers we get:

false//UInt8(10)    #  Rational{UInt8}
1 Like

Yup. I know.
For this reason I was certain when I tested that the input would be accepted.

what can be done with rationals {boolean} is another matter entirely.