# Why doesn't FixedPointNumbers.jl allow comparison with integers?

**URL:** <https://discourse.julialang.org/t/why-doesnt-fixedpointnumbers-jl-allow-comparison-with-integers/77214>\
**Category:** General Usage\
**Tags:** package\
**Created:** [March 1, 2022, 12:55am UTC](https://discourse.julialang.org/t/why-doesnt-fixedpointnumbers-jl-allow-comparison-with-integers/77214 "2022-03-01T00:55:56Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [March 1, 2022, 12:55am UTC](https://discourse.julialang.org/t/why-doesnt-fixedpointnumbers-jl-allow-comparison-with-integers/77214/1 "2022-03-01T00:55:56Z")

</div>

I am using [FixedPointNumbers.jl](https://github.com/JuliaMath/FixedPointNumbers.jl) to implement an approximation algorithm, and I have been running into the following issue:

```julia
julia> using FixedPointNumbers
julia> FP = Fixed{Int16, 4}
Q11f4 (alias for Fixed{Int16, 4})
julia> typemax(FP)
2047.94Q11f4
julia> 2099 > typemax(FP)
ERROR: ArgumentError: Q11f4 is a 16-bit type representing 65536 values from -2048.0 to 2047.94; cannot represent 2099

```

Would you consider this a bug, or is leaving comparisons undefined when number falls out of the type range the standard practice?

If throwing an error as above is the standard practice to prevent overflow issues, what should I do instead? Calling `2099 > Float64(typemax(FP))` feels like overkill.

FWIW, Julia’s builtin types do not have this behavior: `130 > typemax(Int8)` is `true`.

---

<div class="post-metadata">

**Author:** ![halleysfifthinc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/halleysfifthinc/32/206280_2.png) [@halleysfifthinc](https://discourse.julialang.org/u/halleysfifthinc)\
**Post date:** [March 1, 2022, 5:20pm UTC](https://discourse.julialang.org/t/why-doesnt-fixedpointnumbers-jl-allow-comparison-with-integers/77214/2 "2022-03-01T17:20:46Z")

</div>

Looks like there is no specialized method for comparison, so a generic method is attempting to promote the Int to the fixed-point number, and failing since the Int is too large.

An easy fix would be to add a method which first checks if the non fixed-point number is greater/less than the typemax/min of the fixed-point number before trying the promote and compare fallback. Something along the lines of:

```julia
function Base.:<(x::T, y::U) where {T<:Real, U<:FixedPoint}
    if x > round(T, typemax(y), RoundUp)
        return false
    elseif x < round(T, typemin(y), RoundDown)
        return true
    end
    _x, _y = promote(x,y)
    return <(_x.i, _y.i)
end
Base.:<(x::U, y::T) where {U<:Fixed, T<:Real} = !(y < x)

```

```julia
julia> FP = Fixed{Int16, 4}
Q11f4 (alias for Fixed{Int16, 4})

julia> typemin(FP), typemax(FP)
(-2048.0Q11f4, 2047.94Q11f4)

julia> 2099 > typemax(FP)
true

julia> 2040 > typemax(FP)
false

julia> -2099 < typemin(FP)
true

julia> -2040 < typemin(FP)
false

```

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [March 2, 2022, 1:01pm UTC](https://discourse.julialang.org/t/why-doesnt-fixedpointnumbers-jl-allow-comparison-with-integers/77214/3 "2022-03-02T13:01:40Z")

</div>

Nice! But I believe the `promote_rule` for `Fixed` is intentional:

```julia
@show 2048 < 2047.1Q11f4

```

throws

```julia
ERROR: LoadError: ArgumentError: Q11f4 is a 16-bit type representing 65536 values from -2048.0 to 2047.94; cannot represent 2048

```

with your method.

---

<div class="post-metadata">

**Author:** ![halleysfifthinc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/halleysfifthinc/32/206280_2.png) [@halleysfifthinc](https://discourse.julialang.org/u/halleysfifthinc)\
**Post date:** [March 2, 2022, 1:18pm UTC](https://discourse.julialang.org/t/why-doesnt-fixedpointnumbers-jl-allow-comparison-with-integers/77214/4 "2022-03-02T13:18:59Z")

</div>

Good catch! My suggestion doesn’t change promotion or promotion rules, just when promotion happens for this specific case. Looks like the out-of-range comparisons should be ≤ or ≥, since, e.g. for an Int, 2047.1 rounded up to 2048 is also (obviously) too big.

```julia
function Base.:<(x::T, y::U) where {T<:Real, U<:FixedPoint}
    if x >= round(T, typemax(y), RoundUp)
        return false
    elseif x <= round(T, typemin(y), RoundDown)
        return true
    end
    _x, _y = promote(x,y)
    return <(_x.i, _y.i)
end

```

Now:

```julia
julia> @show 2048 < 2047.1Q11f4
2048 < 2047.1Q11f4 = false
false

```
