
John Bytheway wrote:
I tend to use
r = m%n; if (r < 0) r += n;
which the compiler is more likely to implement using a conditional move, rather than a branch (but it does have the issue that it's not an expression).
I have now implemented modulo as template <class T> T modulo(T m, const T& n) { m %= n; if (m < 0) m += n; return m; } and replaced 10 occurrences (all I could find) of (m%n+n)%n with it. Two of these occurrences had the form "(m%std::ptrdiff_t(n)+n)%n", which surprised me a bit. When I replaced them with "modulo(m, n)", the compiler refused to compile it. So I wrote "modulo(m, std::ptrdiff_t(n))" instead, and this compiled fine. Thinking a bit about this, I realized that the template does the right thing by refusing to compile this, whereas the "(m%n+n)%n" construct can lead to surprising results in case n is of type std::size_t. So I think I'm quite happy with my new template. Regards, Thomas