In a different [StackExchange](https://math.stackexchange.com/q/901222), the following algorithm (based on arithmetic coding) was presented as an efficient method for generating outcomes of a 7-sided die, when all that is given is a 6-sided die:

```
int rand7()
{
  static double a=0, width=7;  // persistent state

  while ((int)(a+width) != (int)a)
  {
    width /= 6;
    a += (rand6()-1)*width;
  }

  int n = (int)a;
  a -= n; 
  a *= 7; width *= 7;
  return (n+1);
}

```

Not being a true mathematician, I'll do the best I can to explain how this algorithm works: 

At the start of each call to `rand7()`, `width` is the ratio 7s/6t, and `a` is a non-negative value with the property that `a + width` lies in the interval [0, 7) after the base case. When entering the `while` loop, `width` is the maximal value that can be added to `a`. If `floor(a + width)` is different from `floor(a)`, then a random choice of { 0, `width`\*1/6, `width`\*1/3, `width`\*1/2, `width`\*2/3, `width`\*5/6 } is added to `a`, and the exponent `t` is incremented by one (reducing the value of `width` by a power of 6). Note that after an iteration, the property that `a + width` lies in the interval [0, 7) remains invariant. When `width` becomes smaller than the difference of `ceil(a) - a`, the iterations stop. The loop adds more entropy into `a` so long as doing so can actually affect the outcome of the die roll, and intuitively, *this is building a random real number in the range of [0, 7) using base 6*. After leaving the loop, the die roll is taken to be `floor(a) + 1`, and `a` is reduced to its fractional part. At that point `a + width` lies in the interval [0, 1). To prepare for the next call and to maintain the invariant property, both `a` and `width` are scaled up by a factor of 7 (for `width`, this increases the exponent `s` by 1).

The above explains the workings of the inductive step. Analysis of the base case is left as an exercise for the interested reader.

Of course, from an efficiency standpoint, the use of floating-point arithmetic immediately pops out as a performance drag (assuming the performance of `rand6()` is already sufficient and itself cannot be improved). While maintaining this arithmetic coding algorithm, what is the best approach to removing the use of floating-point?