Enforcing numeric types

I’m trying to write a function that enforces numeric types. The eventualy goal is to create a library to support the use of fixed-point.

So i tried the simple example of

``````function foo(y::UInt8)::UInt8
x::UInt8 = 10
return x+y
end
``````
``````julia> foo(250)
ERROR: MethodError: no method matching foo(::Int64)
``````

so to solve that problem I simply did:

``````julia> foo(convert(UInt8, 250))
0x04
``````

Naturally I would like foo(250) to work. So give that this is a multiple dispatch language I figure that i simply can do:

``````function foo(y)
foo(convert(UInt8, y))
end
``````

and that does in fact do what I want.
I thought this might actually be a good example for those of use new to Julia.

My question is : Is this the right approach ?

My other question is , if i define foo thusly

``````function foo(y::UInt8)::UInt8
x = 10
return x+y
end
``````

and do

``````julia> foo(convert(UInt8, 250))
ERROR: InexactError()
``````

I can see why there would be a problem since I’m sure x is defaulting to Int64, but that doesn’t seem like the right error. Or is it ? I expect that the conversion can’t be done without the possibility of overflow ?

Thanks

In the first case, you can simply call `foo(UInt8(250))`.

The error in your second question is because 260 is larger than `typemax(UInt8)`=255 and you are asking to convert the return value to a `UInt8`. If you make the signature `foo(y::UInt8)` without the `::UInt8`, the return value is a `Int64` as you expect.

Your example works if you defined

``````function foo(y::UInt8)::UInt8
x = UInt8(10)
x + y
end
``````

and would return 0x04. Since you are summing two UInt8 and Julia does not widens automatically the type, you could have written also `function foo(y::UInt8)`.

One more thing: there is no need to do this

because if you pass a UInt8 it will call the more specific method and if you pass any other type, it will throw an error. If you need to have methods that do different things for different input types, you have to define in the same way as you did for `UInt8`:

``````function foo(y::Int) ...
function foo(y::Float64) ...
``````

but you do that only when what you want to do is not captured by a generic method. In your case, because you want to return the same value type as the input, you could simply do

``````function foo(y)
x = convert(typeof(y), 10)
x + y
end
``````

Can you clarify exactly what you want your `foo` function to do? For instance, what do you want to happen when the user calls it with:

1. an out-of-range or negative number?
2. an integer-valued floating-point number like 34.0
3. a fractional floating-point number like 2.6

The `InexactError` is thrown when you try to convert an out-of-range number. You can verify this with `convert(UInt8, 260)`.

Also, have you checked out the FixedPointNumbers package?

Hi,

The idea is tha only unsigned 8 bit values should be handed to the routine and i want the values to wrap. so calling foo(250) and getting back 4 is the desired result.
A value <0 or >255 as an input would be an error.

This was just me using a simple example to make sure I understand how everything works.

@ssfrr : thanks for your help. of course I thought to look for a FixedPointNumbers package right after i posted …
@mzaffalon: Thanks very much for the explanations !

Does this do what you want

``````foo(y) = UInt8(y) + UInt8(10)
``````

?

``````
julia> foo(250)
0x04

julia> foo(-1)
------ InexactError -------------------- Stacktrace (most recent call last)

[1] — foo(::Int64) at REPL[138]:1

InexactError()

julia> foo(256)
------ InexactError -------------------- Stacktrace (most recent call last)

[1] — foo(::Int64) at REPL[138]:1

InexactError()
``````

If I have understood you, then I think this is a better approach. Any number thing that can be converted to a `UInt8` will be, so don’t type the input, except, maybe you should use:

``````foo(y::Number) = UInt8(y) + UInt8(10)
``````