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