Going from int values a=[0,N] to real values x=[0,1] has a fairly obvious algorithm:

  x = a/N
    

Going the other way involves some rounding. We need to preserve the values:

   0/N => 0, 1/N => 1, 2/N => 2, ..., 1 => N
    

But we have a choice of how we pick intermediate values. One way of doing it would be to divide the range [0,1] into (N+1) equal segments, so:

  [0,1/(N+1) [1/(N+1),2/(N+1)) ... [(N-1)/(N+1),N/(N+1)) [N/(N+1),(N+1)/(N+1)]
    

This way of doing it has the nice property that the range [0,1] gets split up equally. Call this method #1.

Another way of doing it would be to use (N+1) segments centered on each of the points 0/N, 1/N, ... 1:

 [-0.5/N,0.5/N) [0.5/N,1.5/N) ... [(N-1.5)/N,(N-0.5)/N) [(N-0.5)/N,(N+0.5)/N]
    

This doesn't preserve equal ranges, but has the elegant (if not particuarly useful?) property that the exact roundtrip values are in the middle of each range. Call this method #2.

There are infinitely many other methods that preserve the inverse mapping, but these are the interesting ones.

The combination of each method with the obvious integer => real method gives corresponding algorithms from going from [0,M] to [O,N]

Method #1:

  b = floor (a*(N+1)/M); a < M. b = N; a == M.
    

Method #2:

  b = floor (a*N/M+0.5)
    

How easy these are to code as integer algorithms depend on the values of N and M. If N+1 divides M+1 exactly (Eg, N=31, M=255), then method #1 is simple. The a < M case is:

  b = floor (a*(N+1)/M) = floor (a*(N+1)/(M+1) + a*(N+1)/[(M+1)*M])
    

Since the second piece inside the floor() is less than (N+1)/(M+1) for a < M, and a == M works as a special case, we can write, for all a.

      b = floor (a*(N+1)/(M+1))
    

But no similarly simple expression is available for method #2. On other other hand, for M = 255*255, N = 255, then method #1 is a little painful to compute as integers; the a < M case is:

  b = floor (a*(256/(255*255)))
    = floor ((a/255 + a)/255)
    = floor ([floor(a/255) + a]/255)
    

Which involves quite few adds and shifts.

      t = a + (a + (a >> 8)) >> 8
      b = (t + (t >> 8)) >> 8
    

But method #2 works out nicely.

  b = floor (a*255 / (255*255) + 0.5 * 255) = floor ((a+127.5)/255)
    

Which is easy to compute:

      t = a + 127
      b = (t + (t >> 8)) >> 8