mbostock/d3 — pull request #2057 by jasondavies (2014-10-10 09:45:53+00:00)
Title: Fix #2039: improve [un]interpolateNumber precision.

**uninterpolate:**

The use of a reciprocal in d3_uninterpolateNumber to avoid division
results in a small loss of precision (the following is a paraphrase):

```js
function d3_uninterpolateNumber(a, b) {
var k = b - a ? 1 / (b - a) : 0;
return function(x) { return (x - a) * k; };
}
```

For x = a, there is no problem, since u = (a - a) * k = 0 * k = 0 as
expected. For x = b, we have u = (b - a) * k, and since k cannot
represent 1 / (b - a) exactly, we don’t get u = 1, but something very
close to 1.

Instead, if we perform the division within the generated function, we
can ensure we always get u = 1 for x = b:

```js
function d3_uninterpolateNumber(a, b) {
var k = b - a || Infinity;
return function(x) { return (x - a) / k; };
}
```

Again, for x = a, we simply have u = (a - a) / k = 0. For x = b, we
have u = (b - a) / k = (b - a) / (b - a) = 1.

**interpolate:**

Similarly, for d3_interpolateNumber, we have a small loss of precision,
this time due to subtraction. Paraphrased:

```js
function d3_interpolateNumber(a, b) {
var d = b - a;
return function(t) { return a + t * d; };
}
```

There is no issue for t = 0, because we always get i = a + 0 * d = a.
However, for t = 1, we get i = a + d, which might not be exactly equal
to b as desired. The following will return precisely b for t = 1:

```js
function d3_interpolateNumber(a, b) {
return function(t) { return a * (1 - t) + b * t; };
}
```