Live data from Hacker News

What the heck is the value of “-n % n” in programming languages?

lemire.me

1–10 of 30 posts

Re: What the heck is the value of “-n % n” in programming languages?

#4
First it's important to note that `n` is unsigned; if it's signed the value of `-n % n` is 0, intuitively.

For unsigned n, the value is: MAX - n + 1 (where max is the maximum representable value in the type of n, e.g., UINT_MAX). The article explains this nicely. (I thought of 2's complement when reasoning through this, but you don't actually need to assume 2's complement to follow the reasoning).

So, `-n % n` computes `(MAX - n + 1) % n` efficiently, without needing to worry about corner cases.

I suspect this is useful when you want to generate random numbers with a limited range, where the range doesn't cleanly divide UINT_MAX. You need to cut a bit off the top from your underlying random number generator.

Re: What the heck is the value of “-n % n” in programming languages?

#10
post #4

First it's important to note that `n` is unsigned; if it's signed the value of `-n % n` is 0, intuitively. For unsigned n, the value is: MAX - n + 1 (where max is the maximum representable value in the type of n, e.g., UINT_MAX). The article explains this nicely. (I thought of 2's complement when reasoning through this, but you don't actually need to assume 2's complement to follow the reasoning). So, `-n % n` comput…

-n % n (where n is unsigned) suffers from the problem that -n calculates a two's complement. That value is implementation-defined, due to the implementation-defined width of the unsigned type.

It's calculating ((-n) mod (2^bits)) mod n, where bits is compiler/platform-dependent.

  ;; TXR Lisp
  1> (defun -n%n (n bits)
       (mod (mod (- n) (expt 2 bits)) n))
  -n%n
  2> (-n%n 7 8)
  4
  3> (-n%n 7 16)
  2
  4> (-n%n 7 17)
  4
  5> (-n%n 7 18)
  1
  6> (-n%n 7 32)
  4
  7> (-n%n 7 64)
  2
I would not use this, except possibly with a precise-width type like uint32_t.
Post reply on HN