# "Not a rational" constant?

In porting some C code I came across a value called NaR, which was defined as Not a Rational (when returned due to error from a function returning a rational). In terms of type consistency, is there a rational in Julia that would be equivalent to NaR?

I suppose 1//0 could be one, and this is what I am now using, but this becomes Inf when converted to float, and I’d prefer it convert to NaN, so that

``````(NaR isa Rational) == true
float(NaR) == NaN
``````

`Rational{T}` is a leaf type for each `T` so you can’t define your own elements in the type.

There’s no problem with making your own function. Something along the lines of

``````function finitefloat(x)
f = float(x)
return isfinite(f) ? f : oftype(f,NaN)
end
``````

Note: changing how rationals interact with general functions without going through wrappers like this example is not something easy to do without the extremely dangerous and strongly discouraged act of type piracy (and even then, is only “easy” if it doesn’t accidentally break a bunch of other stuff you’re trying to use).

Theoretically NaN could map to `0//0`, but that’s explicitly not allowed:

``````julia> 0//0
ERROR: ArgumentError: invalid rational: zero(Int64)//zero(Int64)
``````

Instead, I’d probably return `missing` in situations like this and explicitly `coalesce` to `NaN` upon converting to float.

3 Likes

What is the reasoning here? Seems rather inconsistent to me.
Also I find the errors to be inconsistent:

``````0//0 # ArgumentError of constructor, explains zero/zero is invalid Rational
(1//0)*0 # DivideError in gcd, says division by 0 not allowed
``````

The reasoning is basically just that allowing `1//0` and `-1//0` as infinite values works out well in the math without adding extra checks while supporting `0//0` adds a special case to basically any function that deals with rationals.

2 Likes