# The guidance using % vs @rem/@mod

Hi,

Working my way through Exercism Zig exercises (and mentoring some) I have noticed that many people make use of `@mod`/`@rem` instead of more conventional `%` for integer divisibility checks. I would like to understand what’s the preferred approach that’s idiomatic for Zig.

In ziglang/zig#217 `%` was removed for signed integers. When attempting to use it the compiler would suggest to use `@mod`/`@rem` instead. The documentation only states that for signed unsigned integers both functions behave exactly as `%` without recommending one over the other.

Following Zig’s principle of “only one obvious way to do things”, I could imagine the following guidance:

• use `%` for unsigned integers
• use `@mod`/`@rem` for signed integers depending on what behavior is desired

Is this correct understanding? Do I miss any important aspects?

You misread that that. It states that they behave the same for unsigned integers (all values >= 0).

In general I would do the following:

• use `%` for unsigned integers
• if you know that your numbers are positive then you should change the types to unsigned
• use `@rem` if you want the same behavior as `%` in other languages
• use `@mod` if you want the mathematical modulo, aka difference to the next smaller number divisble by `y`
• use `@rem` if you want the difference to the next number divisble by `y` that is smaller in absolute value. Note the following relation between the two: `@rem(x, y) == math.sign(x)*@mod(@abs(x), y)`

Two more things to note with regards to performance:
`@rem(x, y)` is usually implemented in hardware, so it will be faster in most cases.
However if the right hand side is a comptime-known power of 2 then `@mod(x, y)` will be faster.

6 Likes

Thanks for the detailed response! And sorry for the confusing typo.

Do you think it would make sense to suggest in the documentation for `@rem`/`@mod` that `%` is preferable for unsigned integers?

No, I think it just comes down to personal preference.
I don’t see any real reason to discourage using `@mod`/`@rem` for unsigned integers.
For example for people coming from a math background I think `@mod` might actually be more readable.

1 Like

Where’s @divmod? Please don’t say you forgot it.

I haven’t run into `@divmod` in Zig before nor do I see it in the documentation. Would be happy to learn about it though.