# Help to create a macro do avoid integer overflow

Hi guys!

I need help to create a macro to do the following:

• On every integer operation, check if overflow will happen.
• If it does, then promote the arguments to integer representations with higher number of bits.

I do not know how the compiler will work, but I am wondering if this can be done without much performance decrease if the operands do not lead to an integer overflow.

My usage is because I have in my code things like:

``````f100 = C1*Δt^2 + C2*Δt^3
``````

where `Δt` is selected by the user and can be a very big number. Hence, if the user input a big integer, the `^` will overflow.

Of course I can always promote the `Δt` to Float64, but I want to try this to see how it works.

Macros don’t know about types, so macros can’t do this. If you want different integer semantics, you generally need to define a different integer type. (See e.g. https://github.com/JeffreySarnoff/SaferIntegers.jl)

If you only want to look at operations on integer literals, that could be done with a macro, but I’m not sure how useful it would be.

If it does, then promote the arguments to integer representations with higher number of bits. I do not know how the compiler will work, but I am wondering if this can be done without much performance decrease if the operands do not lead to an integer overflow.

I doubt that this can be done at runtime without a substantial performance hit, but you are welcome to try to define a type that behaves in this way.

1 Like

Hi @stevengj,

Thanks for the answer, but by macro, I mean something like `@inbounds` that I can add to certain operations so that they can behave like I described.

A macro is just a rewrite of an expression into another. What expression do you want to apply the macro to and what expression do you want to come out in the end?

1 Like

I understood. But, I really do not know I want something that, at every integer operation (+, * and ^) it checks the operands and, if overflow will happen, then change the type to a representation with higher bit. I have no idea how to code this in Julia.

Why don’t you use https://github.com/JeffreySarnoff/SaferIntegers.jl ?

1 Like

There is no way to know that at compile time, so macros will not help you. You should use `try` blocks with the saferintegers.

For three reasons:

1. It does not support (at least it is not documented) the function `^`.
2. I want to learn new things
3. I want to see the performance hit when doing such things like check the type and promoting if necessary.

Actually, I am thinking of a macro that overload / change (do not know the correct name) the operations. Something like, change `+` to another function that performs the verification as I described. This macro will be used just trigger such behavior like:

``````@check_overflow f100 = C1*Δt^2 + C2*Δt^3
``````

However, if I give up and use SafeIntegers, I would do something like:

``````try
f100 = C1*Δt^2 + C2*Δt^3
catch
f100 = C1*BigInt(Δt)^ + C2*BigInt(Δt)^3
end
``````

Correct?

I think this is exactly what SaferIntegers does. It creates primitives that work the same way as integers but checks for overflow by defining their own methods for common functions.

2 Likes

Nice! I will see The macro I mentioned is because I just want to do this in some parts of the code, because there are other in which I know it is not necessary. Hence, I think if I can trigger this behavior only when necessary, the performance hit will not be big (at least I hope).

Anyway, in some tests here with SafeIntegers and such things, I am starting to see that my best approach in terms of performance is to convert everything to Float64 just as MATLAB does

You could a macro that does something where `@check_overflow f100 = C1*Δt^2 + C2*Δt^3` lowers to

``````try
f100 = C1*SafeInt(Δt)^2 + C2*SafeInt(Δt)^3
catch
f100 = C1*BigInt(Δt)^ + C2*BigInt(Δt)^3
end
``````

Presumably there was a reason you used Integers in the first place?

Actually I am using Numbers. The user decide. The input variable is the number of seconds from a specific epoch. Hence, many users will like to write something like:

``````propagate!(orbs, 1000)
``````

Instead of

``````propagate!(orbs, 100.0)
``````

I would not like to force them to use Float literals because this is targeted to MATLAB users.

In this case you could do something along

``````function propagate!(a,s::Float64)
#define function here
...
end

propagate!(a,s::Number) = propagate!(a,float(s))``````
1 Like

Yeah, that is what I mentioned before. I am starting to think this is the best approach, which is basically what MATLAB does, convert everything to Double.