I simplified the implementation, though it still seems somewhat magical. I
would be more confident if there were an easy way to extract the mantissa and
exponent from a floating point number, but since JavaScript does not expose the
bitwise representation of numbers, there's no easy way to do it.
This commit is contained in:
Mike Bostock 2012-02-18 13:05:02 -08:00
Родитель c3516c06a6 8178c2961b
Коммит 1643aa9b46
4 изменённых файлов: 34 добавлений и 18 удалений

19
d3.js поставляемый
Просмотреть файл

@ -391,11 +391,6 @@ function d3_splitter(d) {
function d3_collapse(s) {
return s.replace(/(^\s+)|(\s+$)/g, "").replace(/\s+/g, " ");
}
/**
* @param {number} start
* @param {number=} stop
* @param {number=} step
*/
d3.range = function(start, stop, step) {
if (arguments.length < 3) {
step = 1;
@ -404,14 +399,22 @@ d3.range = function(start, stop, step) {
start = 0;
}
}
if ((stop - start) / step == Infinity) throw new Error("infinite range");
if ((stop - start) / step === Infinity) throw new Error("infinite range");
var range = [],
k = d3_range_integerScale(Math.abs(step)),
i = -1,
j;
if (step < 0) while ((j = start + step * ++i) > stop) range.push(j);
else while ((j = start + step * ++i) < stop) range.push(j);
start *= k, stop *= k, step *= k;
if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k);
else while ((j = start + step * ++i) < stop) range.push(j / k);
return range;
};
function d3_range_integerScale(x) {
var k = 1;
while (x * k % 1) k *= 10;
return k;
}
d3.requote = function(s) {
return s.replace(d3_requote_re, "\\$&");
};

4
d3.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1,8 +1,3 @@
/**
* @param {number} start
* @param {number=} stop
* @param {number=} step
*/
d3.range = function(start, stop, step) {
if (arguments.length < 3) {
step = 1;
@ -11,11 +6,19 @@ d3.range = function(start, stop, step) {
start = 0;
}
}
if ((stop - start) / step == Infinity) throw new Error("infinite range");
if ((stop - start) / step === Infinity) throw new Error("infinite range");
var range = [],
k = d3_range_integerScale(Math.abs(step)),
i = -1,
j;
if (step < 0) while ((j = start + step * ++i) > stop) range.push(j);
else while ((j = start + step * ++i) < stop) range.push(j);
start *= k, stop *= k, step *= k;
if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k);
else while ((j = start + step * ++i) < stop) range.push(j / k);
return range;
};
function d3_range_integerScale(x) {
var k = 1;
while (x * k % 1) k *= 10;
return k;
}

Просмотреть файл

@ -36,6 +36,16 @@ suite.addBatch({
assert.deepEqual(range(5, 8.5, .5), [5, 5.5, 6, 6.5, 7, 7.5, 8]);
assert.deepEqual(range(2, 0, -.5), [2, 1.5, 1, .5]);
},
"handles fractional steps without rounding errors": function(range) {
assert.deepEqual(range(0, 0.5, 0.1), [0, 0.1, 0.2, 0.3, 0.4]);
assert.deepEqual(range(-2, -1.2, 0.1), [-2, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3]);
},
"handles extremely small steps without rounding errors": function(range) {
assert.deepEqual(range(2.1e-31, 5e-31, 1.1e-31), [2.1e-31, 3.2e-31, 4.3e-31]);
},
"handles extremely large steps without rounding errors": function(range) {
assert.deepEqual(range(1e300, 2e300, 0.3e300), [1e300, 1.3e300, 1.6e300, 1.9e300]);
},
"returns an ascending range if step is positive": function(range) {
assert.deepEqual(range(0, 5, 1), [0, 1, 2, 3, 4]);
},