# Floating point fun: iterating the number space

As a joke the other day I posted a code snippet on Mastodon:

```for (var i = -Infinity; i < Infinity; i++) {
/* this should cover all possibilities */
}```

Such an infinite loop is not possible, as adding 1 to -Infinity just gives you -Infinity again, and you never get anywhere. ;)

But even if you started from the minimum representable individual number in a double-precision floating point you wouldn’t actually iterate anywhere because there’s not enough precision to represent the added 1.

Which got me thinking, how *would* you iterate over the entire set of floating point numbers between -Infinity to +Infinity, knowing that the intervals between the numbers are variable?

Well if you want to get everything, including non-integral values, you can iterate over the available range of exponents and fractional values, and either bit-shift them together manually (ick!) or multiply/add/pow them together in floating point land.

Something like this:

```function iterate_all_floats(callback) {
// exponent is additively biased in the binary rep,
// so we go from negative to positive vals.
let min_exp = -(Math.pow(2, 10) - 2); // all binary 1s are reserved
let max_exp = Math.pow(2, 10) - 1;

let min_frac = 0;
let max_frac = Math.pow(2, 52) - 1;
let frac_divisor = Math.pow(2, 52);

let min_sub = 0;
let max_sub = Math.pow(2, 52) - 1;
let sub_divisor = Math.pow(2, 52);

callback(-Infinity);

// Start from the biggest negative numbers and go up towards -0
for (let exp = max_exp; exp >= min_exp; exp--) {
for (let frac = max_frac; frac >= min_frac; frac--) {
callback(-(1.0 + frac / frac_divisor) * Math.pow(2, exp));
}
}

// Negative subnormals and -0
for (let sub = max_sub; sub >= min_sub; sub--) {
callback(-(sub / sub_divisor) * Math.pow(2, -1022));
}

// +0 and positive subnormals
for (let sub = min_sub; sub <= max_sub; sub++) {
callback((sub / sub_divisor) * Math.pow(2, -1022));
}

// Start from just past +0 and move up to the biggest numbers
for (let exp = max_exp; exp <= max_exp; exp++) {
for (let frac = min_frac; frac <= max_frac; frac++) {
callback((1.0 + frac / frac_divisor) * Math.pow(2, exp));
}
}

callback(Infinity);
}

iterate_all_floats(function(f) {
// Convert to binary for display
let floats = new Float64Array(1);
let bytes = new Uint8Array(floats.buffer);
let str = '';
floats = f;
for (let i = 3; i >= 0; i--) {
let b = bytes[i];
for (let bit = 7; bit >= 0; bit--) {
let val = (b >> bit) & 1;
str += val;
}
}
console.log(str, f);
});```

Enjoy!