| /* |
| * Any copyright is dedicated to the Public Domain. |
| * http://creativecommons.org/licenses/publicdomain/ |
| */ |
| |
| // Some tests regarding conversion to Float32 |
| assertEq(Math.fround(), NaN); |
| |
| // Special values |
| assertEq(Math.fround(NaN), NaN); |
| assertEq(Math.fround(-Infinity), -Infinity); |
| assertEq(Math.fround(Infinity), Infinity); |
| assertEq(Math.fround(-0), -0); |
| assertEq(Math.fround(+0), +0); |
| |
| // Polyfill function for Float32 conversion |
| var toFloat32 = (function() { |
| var f32 = new Float32Array(1); |
| function f(x) { |
| f32[0] = x; |
| return f32[0]; |
| } |
| return f; |
| })(); |
| |
| // A test on a certain range of numbers, including big numbers, so that |
| // we get a loss in precision for some of them. |
| for (var i = 0; i < 64; ++i) { |
| var p = Math.pow(2, i) + 1; |
| assertEq(Math.fround(p), toFloat32(p)); |
| assertEq(Math.fround(-p), toFloat32(-p)); |
| } |
| |
| /******************************************** |
| /* Tests on maximal Float32 / Double values * |
| /*******************************************/ |
| function maxValue(exponentWidth, significandWidth) { |
| var n = 0; |
| var maxExp = Math.pow(2, exponentWidth - 1) - 1; |
| for (var i = significandWidth; i >= 0; i--) |
| n += Math.pow(2, maxExp - i); |
| return n; |
| } |
| |
| var DBL_MAX = maxValue(11, 52); |
| assertEq(DBL_MAX, Number.MAX_VALUE); // sanity check |
| |
| // Finite as a double, too big for a float |
| assertEq(Math.fround(DBL_MAX), Infinity); |
| |
| var FLT_MAX = maxValue(8, 23); |
| assertEq(Math.fround(FLT_MAX), FLT_MAX); |
| assertEq(Math.fround(FLT_MAX + Math.pow(2, Math.pow(2, 8 - 1) - 1 - 23 - 2)), FLT_MAX); // round-nearest rounds down to FLT_MAX |
| assertEq(Math.fround(FLT_MAX + Math.pow(2, Math.pow(2, 8 - 1) - 1 - 23 - 1)), Infinity); // no longer rounds down to FLT_MAX |
| |
| /********************************************************* |
| /******* Tests on denormalizations and roundings ********* |
| /********************************************************/ |
| |
| function minValue(exponentWidth, significandWidth) { |
| return Math.pow(2, -(Math.pow(2, exponentWidth - 1) - 2) - significandWidth); |
| } |
| |
| var DBL_MIN = Math.pow(2, -1074); |
| assertEq(DBL_MIN, Number.MIN_VALUE); // sanity check |
| |
| // Too small for a float |
| assertEq(Math.fround(DBL_MIN), 0); |
| |
| var FLT_MIN = minValue(8, 23); |
| assertEq(Math.fround(FLT_MIN), FLT_MIN); |
| |
| assertEq(Math.fround(FLT_MIN / 2), 0); // halfway, round-nearest rounds down to 0 (even) |
| assertEq(Math.fround(FLT_MIN / 2 + Math.pow(2, -202)), FLT_MIN); // first double > FLT_MIN / 2, rounds up to FLT_MIN |
| |
| assertEq(Math.fround(-FLT_MIN), -FLT_MIN); |
| |
| assertEq(Math.fround(-FLT_MIN / 2), -0); // halfway, round-nearest rounds up to -0 (even) |
| assertEq(Math.fround(-FLT_MIN / 2 - Math.pow(2, -202)), -FLT_MIN); // first double < -FLT_MIN / 2, rounds down to -FLT_MIN |
| |
| reportCompare(0, 0, "ok"); |