| //------------------------------------------------------------------------------------------------------- |
| // Copyright (C) Microsoft. All rights reserved. |
| // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. |
| //------------------------------------------------------------------------------------------------------- |
| |
| // ES6 Math API extensions tests -- verifies the API shape and basic functionality |
| |
| WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js"); |
| |
| // WARNING!! As a convenience in this test suite assert.areEqual is |
| // overridden so that -0 does not equal +0. The tests here all make |
| // the distinction between negative and positive zero. |
| assert.areEqual = (function () { |
| var areEqual = assert.areEqual; |
| |
| return function (expected, actual, message) { |
| if (expected === 0 && actual === 0) { |
| var isNegativeZero = function isNegativeZero(x) { return x === 0 && (1 / x) === -Infinity; }; |
| |
| if (isNegativeZero(expected) !== isNegativeZero(actual)) { |
| if (isNegativeZero(expected)) expected = "-0"; |
| if (isNegativeZero(actual)) actual = "-0"; |
| |
| throw "assert.areEqualSignedZero failed: expected: " + expected + " actual: " + actual + (message !== undefined ? ": " + message : ""); |
| } |
| } |
| return areEqual(expected, actual, message); |
| }; |
| })(); |
| |
| var assertFunctionExactlyEqual = function (expected, fn, x, message) { |
| assert.areEqual(expected, fn(x), message); |
| }; |
| |
| var assertFunctionExactlyEqual2 = function (expected, fn, x, y, message) { |
| assert.areEqual(expected, fn(x, y), message); |
| }; |
| |
| var assertFunctionExactlyEqual3 = function (expected, fn, x, y, z, message) { |
| assert.areEqual(expected, fn(x, y, z), message); |
| }; |
| |
| var assertFunctionExactlyEqual4 = function (expected, fn, x, y, z, w, message) { |
| assert.areEqual(expected, fn(x, y, z, w), message); |
| }; |
| |
| var assertFunctionExactlyEqual7 = function (expected, fn, x, y, z, w, a, b, c, message) { |
| assert.areEqual(expected, fn(x, y, z, w, a, b, c), message); |
| }; |
| |
| var assertFunctionAlmostEqual = function (expected, fn, x, message) { |
| assert.areAlmostEqual(expected, fn(x), message); |
| }; |
| |
| var assertFunctionAlmostEqual2 = function (expected, fn, x, y, message) { |
| assert.areAlmostEqual(expected, fn(x, y), message); |
| }; |
| |
| var assertFunctionAlmostEqual3 = function (expected, fn, x, y, z, message) { |
| assert.areAlmostEqual(expected, fn(x, y, z), message); |
| }; |
| |
| var tests = [ |
| { |
| name: "Math object should have spec defined built-ins with correct lengths", |
| body: function () { |
| assert.isTrue(Math.hasOwnProperty('log10'), "Math should have a log10 method"); |
| assert.isTrue(Math.hasOwnProperty('log2'), "Math should have a log2 method"); |
| assert.isTrue(Math.hasOwnProperty('log1p'), "Math should have a log1p method"); |
| assert.isTrue(Math.hasOwnProperty('expm1'), "Math should have a expm1 method"); |
| assert.isTrue(Math.hasOwnProperty('cosh'), "Math should have a cosh method"); |
| assert.isTrue(Math.hasOwnProperty('sinh'), "Math should have a sinh method"); |
| assert.isTrue(Math.hasOwnProperty('tanh'), "Math should have a tanh method"); |
| assert.isTrue(Math.hasOwnProperty('acosh'), "Math should have a acosh method"); |
| assert.isTrue(Math.hasOwnProperty('asinh'), "Math should have a asinh method"); |
| assert.isTrue(Math.hasOwnProperty('atanh'), "Math should have a atanh method"); |
| assert.isTrue(Math.hasOwnProperty('hypot'), "Math should have a hypot method"); |
| assert.isTrue(Math.hasOwnProperty('trunc'), "Math should have a trunc method"); |
| assert.isTrue(Math.hasOwnProperty('sign'), "Math should have a sign method"); |
| assert.isTrue(Math.hasOwnProperty('cbrt'), "Math should have a cbrt method"); |
| assert.isTrue(Math.hasOwnProperty('imul'), "Math should have a imul method"); |
| assert.isTrue(Math.hasOwnProperty('clz32'), "Math should have a clz32 method"); |
| |
| assert.isTrue(Math.log10.length === 1, "log10 method takes one argument"); |
| assert.isTrue(Math.log2.length === 1, "log2 method takes one argument"); |
| assert.isTrue(Math.log1p.length === 1, "log1p method takes one argument"); |
| assert.isTrue(Math.expm1.length === 1, "expm1 method takes one argument"); |
| assert.isTrue(Math.cosh.length === 1, "cosh method takes one argument"); |
| assert.isTrue(Math.sinh.length === 1, "sinh method takes one argument"); |
| assert.isTrue(Math.tanh.length === 1, "tanh method takes one argument"); |
| assert.isTrue(Math.acosh.length === 1, "acosh method takes one argument"); |
| assert.isTrue(Math.asinh.length === 1, "asinh method takes one argument"); |
| assert.isTrue(Math.atanh.length === 1, "atanh method takes one argument"); |
| assert.isTrue(Math.hypot.length === 2, "hypot method takes three arguments but the third is optional and spec says the length must be 2"); |
| assert.isTrue(Math.trunc.length === 1, "trunc method takes one argument"); |
| assert.isTrue(Math.sign.length === 1, "sign method takes one argument"); |
| assert.isTrue(Math.cbrt.length === 1, "cbrt method takes one argument"); |
| assert.isTrue(Math.imul.length === 2, "imul method takes two arguments"); |
| assert.isTrue(Math.clz32.length === 1, "clz32 method takes one argument"); |
| } |
| }, |
| { |
| name: "Math APIs all return NaN if called with no arguments or passed undefined for arguments", |
| body: function () { |
| assert.areEqual(NaN, Math.log10(), "log10 returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.log2(), "log2 returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.log1p(), "log1p returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.expm1(), "expm1 returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.cosh(), "cosh returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.sinh(), "sinh returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.tanh(), "tanh returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.acosh(), "acosh returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.asinh(), "asinh returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.atanh(), "atanh returns NaN given no arguments"); |
| assert.areEqual( +0, Math.hypot(), "hypot returns +0 given no arguments"); |
| assert.areEqual(123, Math.hypot(123), "hypot returns abs(123) given only one argument"); |
| assert.areEqual(123, Math.hypot(-123), "hypot returns abs(-123) given only one argument"); |
| assert.areEqual(NaN, Math.trunc(), "trunc returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.sign(), "sign returns NaN given no arguments"); |
| assert.areEqual(NaN, Math.cbrt(), "cbrt returns NaN given no arguments"); |
| // imul actually returns +0 since it converts its arguments via ToUint32 which converts undefined to 0 |
| assert.areEqual( +0, Math.imul(), "imul returns +0 given no arguments"); |
| assert.areEqual( +0, Math.imul(123), "imul returns +0 given too few arguments"); |
| |
| assert.areEqual(NaN, Math.log10(undefined), "log10 returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.log2(undefined), "log2 returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.log1p(undefined), "log1p returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.expm1(undefined), "expm1 returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.cosh(undefined), "cosh returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.sinh(undefined), "sinh returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.tanh(undefined), "tanh returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.acosh(undefined), "acosh returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.asinh(undefined), "asinh returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.atanh(undefined), "atanh returns NaN when passed undefined"); |
| /* |
| assert.areEqual(NaN, Math.hypot(undefined, undefined), "hypot returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.hypot(undefined, undefined, undefined), "hypot returns NaN when passed undefined"); |
| */ |
| assert.areEqual(NaN, Math.trunc(undefined), "trunc returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.sign(undefined), "sign returns NaN when passed undefined"); |
| assert.areEqual(NaN, Math.cbrt(undefined), "cbrt returns NaN when passed undefined"); |
| assert.areEqual( +0, Math.imul(undefined), "imul returns +0 when passed undefined"); |
| assert.areEqual( +0, Math.imul(undefined, undefined), "imul returns +0 when passed undefined"); |
| } |
| }, |
| { |
| name: "log10 computes the base 10 logarithm and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.log10, NaN, "if x is NaN, then the result of log10(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.log10, -1, "if x is less than 0, then the result of log10(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.log10, -500, "if x is less than 0, then the result of log10(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.log10, -Infinity, "if x is less than 0, then the result of log10(x) is NaN"); |
| assertFunctionExactlyEqual(-Infinity, Math.log10, +0, "if x is +0, then the result of log10(x) is -Infinity"); |
| assertFunctionExactlyEqual(-Infinity, Math.log10, -0, "if x is -0, then the result of log10(x) is -Infinity"); |
| assertFunctionExactlyEqual( +0, Math.log10, 1, "if x is 1, then the result of log10(x) is +0"); |
| assertFunctionExactlyEqual(+Infinity, Math.log10, +Infinity, "if x is +Infinity, then the result of log10(x) is +Infinity"); |
| |
| assertFunctionAlmostEqual( 1, Math.log10, 10, "log10(10) = 1"); |
| assertFunctionAlmostEqual( 2, Math.log10, 100, "log10(100) = 2"); |
| assertFunctionAlmostEqual( 6, Math.log10, 1000000, "log10(100) = 6"); |
| } |
| }, |
| { |
| name: "log2 computes the base 2 logarithm and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.log2, NaN, "if x is NaN, then the result of log2(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.log2, -1, "if x is less than 0, then the result of log2(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.log2, -500, "if x is less than 0, then the result of log2(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.log2, -Infinity, "if x is less than 0, then the result of log2(x) is NaN"); |
| assertFunctionExactlyEqual(-Infinity, Math.log2, +0, "if x is +0, then the result of log2(x) is -Infinity"); |
| assertFunctionExactlyEqual(-Infinity, Math.log2, -0, "if x is -0, then the result of log2(x) is -Infinity"); |
| assertFunctionExactlyEqual( +0, Math.log2, 1, "if x is 1, then the result of log2(x) is +0"); |
| assertFunctionExactlyEqual(+Infinity, Math.log2, +Infinity, "if x is +Infinity, then the result of log2(x) is +Infinity"); |
| |
| assertFunctionAlmostEqual( 1, Math.log2, 2, "log2(2) = 1"); |
| assertFunctionAlmostEqual( 2, Math.log2, 4, "log2(4) = 2"); |
| assertFunctionAlmostEqual( 6, Math.log2, 64, "log2(64) = 6"); |
| } |
| }, |
| { |
| name: "log1p computes the natural logarithm of 1 + x and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.log1p, NaN, "if x is NaN, then the result of log1p(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.log1p, -2, "if x is less than -1, then the result of log1p(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.log1p, -500, "if x is less than -1, then the result of log1p(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.log1p, -Infinity, "if x is less than -1, then the result of log1p(x) is NaN"); |
| assertFunctionExactlyEqual(-Infinity, Math.log1p, -1, "if x is -1, then the result of log1p(x) is -Infinity"); |
| assertFunctionExactlyEqual( +0, Math.log1p, +0, "if x is +0, then the result of log1p(x) is +0"); |
| assertFunctionExactlyEqual( -0, Math.log1p, -0, "if x is -0, then the result of log1p(x) is -0"); |
| assertFunctionExactlyEqual(+Infinity, Math.log1p, +Infinity, "if x is +Infinity, then the result of log1p(x) is +Infinity"); |
| |
| var e = Math.E; |
| var e2 = e * e; |
| var e6 = e2 * e2 * e2; |
| |
| assertFunctionAlmostEqual( 1, Math.log1p, e - 1, "log1p(e - 1) = 1"); |
| assertFunctionAlmostEqual( 2, Math.log1p, e2 - 1, "log1p(e^2 - 1) = 2"); |
| assertFunctionAlmostEqual( 6, Math.log1p, e6 - 1, "log1p(e^6 - 1) = 6"); |
| |
| // TODO: Figure out how to run these tests on machines with C99 APIs |
| /* |
| assertFunctionAlmostEqual( 1e-20, Math.log1p, 1e-20, "log1p(10^-20) = 10^-20"); |
| assertFunctionAlmostEqual( 1e-30, Math.log1p, 1e-30, "log1p(10^-30) = 10^-30"); |
| assertFunctionAlmostEqual( 1e-50, Math.log1p, 1e-50, "log1p(10^-50) = 10^-50"); |
| */ |
| } |
| }, |
| { |
| name: "expm1 computes the result of subtracting 1 from the exponential function and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.expm1, NaN, "if x is NaN, then the result of expm1(x) is NaN"); |
| assertFunctionExactlyEqual( +0, Math.expm1, +0, "if x is +0, then the result of expm1(x) is +0"); |
| assertFunctionExactlyEqual( -0, Math.expm1, -0, "if x is -0, then the result of expm1(x) is -0"); |
| assertFunctionExactlyEqual(+Infinity, Math.expm1, +Infinity, "if x is +Infinity, then the result of expm1(x) is +Infinity"); |
| assertFunctionExactlyEqual( -1, Math.expm1, -Infinity, "if x is -Infinity, then the result of expm1(x) is -1"); |
| |
| var e = Math.E; |
| var e2 = e * e; |
| var e6 = e2 * e2 * e2; |
| |
| assertFunctionAlmostEqual( e - 1, Math.expm1, 1, "expm1(1) = e - 1"); |
| assertFunctionAlmostEqual( e2 - 1, Math.expm1, 2, "expm1(2) = e^2 - 1"); |
| assertFunctionAlmostEqual( e6 - 1, Math.expm1, 6, "expm1(6) = e^6 - 1"); |
| |
| // TODO: Figure out how to run these tests on machines with C99 APIs |
| /* |
| assertFunctionAlmostEqual( 1e-20, Math.expm1, 1e-20, "expm1(10^-20) = 10^-20"); |
| assertFunctionAlmostEqual( 1e-30, Math.expm1, 1e-30, "expm1(10^-30) = 10^-30"); |
| assertFunctionAlmostEqual( 1e-50, Math.expm1, 1e-50, "expm1(10^-50) = 10^-50"); |
| */ |
| } |
| }, |
| { |
| name: "cosh computes the hyperbolic cosine and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.cosh, NaN, "if x is NaN, then the result of cosh(x) is NaN"); |
| assertFunctionExactlyEqual( 1, Math.cosh, +0, "if x is +0, then the result of cosh(x) is 1"); |
| assertFunctionExactlyEqual( 1, Math.cosh, -0, "if x is -0, then the result of cosh(x) is 1"); |
| assertFunctionExactlyEqual(+Infinity, Math.cosh, +Infinity, "if x is +Infinity, then the result of cosh(x) is +Infinity"); |
| assertFunctionExactlyEqual(+Infinity, Math.cosh, -Infinity, "if x is -Infinity, then the result of cosh(x) is +Infinity"); |
| |
| var e = Math.E; |
| var e2 = e * e; |
| var em2 = 1 / e2; |
| |
| var cosh1 = (e + 1/e) / 2; |
| var cosh2 = (e2 + em2) / 2; |
| |
| assertFunctionAlmostEqual( cosh1, Math.cosh, 1, "cosh(1) = (e + e^-1) / 2"); |
| assertFunctionAlmostEqual( cosh2, Math.cosh, 2, "cosh(2) = (e^2 + e^-2) / 2"); |
| } |
| }, |
| { |
| name: "sinh computes the hyperbolic sine and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.sinh, NaN, "if x is NaN, then the result of sinh(x) is NaN"); |
| assertFunctionExactlyEqual( +0, Math.sinh, +0, "if x is +0, then the result of sinh(x) is +0"); |
| assertFunctionExactlyEqual( -0, Math.sinh, -0, "if x is -0, then the result of sinh(x) is -0"); |
| assertFunctionExactlyEqual(+Infinity, Math.sinh, +Infinity, "if x is +Infinity, then the result of sinh(x) is +Infinity"); |
| assertFunctionExactlyEqual(-Infinity, Math.sinh, -Infinity, "if x is -Infinity, then the result of sinh(x) is -Infinity"); |
| |
| var e = Math.E; |
| var e2 = e * e; |
| var em2 = 1 / e2; |
| |
| var sinh1 = (e - 1/e) / 2; |
| var sinh2 = (e2 - em2) / 2; |
| |
| assertFunctionAlmostEqual( sinh1, Math.sinh, 1, "sinh(1) = (e - e^-1) / 2"); |
| assertFunctionAlmostEqual( sinh2, Math.sinh, 2, "sinh(2) = (e^2 - e^-2) / 2"); |
| } |
| }, |
| { |
| name: "tanh computes the hyperbolic tangent and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.tanh, NaN, "if x is NaN, then the result of tanh(x) is NaN"); |
| assertFunctionExactlyEqual( +0, Math.tanh, +0, "if x is +0, then the result of tanh(x) is +0"); |
| assertFunctionExactlyEqual( -0, Math.tanh, -0, "if x is -0, then the result of tanh(x) is -0"); |
| assertFunctionExactlyEqual( 1, Math.tanh, +Infinity, "if x is +Infinity, then the result of tanh(x) is 1"); |
| assertFunctionExactlyEqual( -1, Math.tanh, -Infinity, "if x is -Infinity, then the result of tanh(x) is -1"); |
| |
| var tanh1 = Math.sinh(1) / Math.cosh(1); |
| var tanh2 = Math.sinh(2) / Math.cosh(2); |
| |
| assertFunctionAlmostEqual( tanh1, Math.tanh, 1, "tanh(1) = sinh(1) / cosh(1)"); |
| assertFunctionAlmostEqual( tanh2, Math.tanh, 2, "tanh(2) = sinh(2) / cosh(2)"); |
| } |
| }, |
| { |
| name: "acosh computes the inverse hyperbolic cosine and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.acosh, NaN, "if x is NaN, then the result of acosh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.acosh, 0.999, "if x is less than 1, then the result of acosh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.acosh, 0.5, "if x is less than 1, then the result of acosh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.acosh, 0, "if x is less than 1, then the result of acosh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.acosh, -1, "if x is less than 1, then the result of acosh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.acosh, -Infinity, "if x is less than 1, then the result of acosh(x) is NaN"); |
| assertFunctionExactlyEqual( +0, Math.acosh, 1, "if x is 1, then the result of acosh(x) is +0"); |
| assertFunctionExactlyEqual(+Infinity, Math.acosh, +Infinity, "if x is +Infinity, then the result of acosh(x) is +Infinity"); |
| |
| var acosh2 = Math.log(2 + Math.sqrt(3)); |
| var acosh3 = Math.log(3 + Math.sqrt(8)); |
| |
| assertFunctionAlmostEqual( acosh2, Math.acosh, 2, "acosh(2) = ln(2 + sqrt(3))"); |
| assertFunctionAlmostEqual( acosh3, Math.acosh, 3, "acosh(3) = ln(3 + sqrt(8))"); |
| } |
| }, |
| { |
| name: "asinh computes the inverse hyperbolic sine and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.asinh, NaN, "if x is NaN, then the result of asinh(x) is NaN"); |
| assertFunctionExactlyEqual( +0, Math.asinh, +0, "if x is +0, then the result of asinh(x) is +0"); |
| assertFunctionExactlyEqual( -0, Math.asinh, -0, "if x is -0, then the result of asinh(x) is -0"); |
| assertFunctionExactlyEqual(+Infinity, Math.asinh, +Infinity, "if x is +Infinity, then the result of asinh(x) is +Infinity"); |
| assertFunctionExactlyEqual(-Infinity, Math.asinh, -Infinity, "if x is -Infinity, then the result of asinh(x) is -Infinity"); |
| |
| var asinh1 = Math.log(1 + Math.SQRT2); |
| var asinh2 = Math.log(2 + Math.sqrt(5)); |
| |
| assertFunctionAlmostEqual( asinh1, Math.asinh, 1, "asinh(1) = ln(1 + sqrt(2))"); |
| assertFunctionAlmostEqual( asinh2, Math.asinh, 2, "asinh(2) = ln(2 + sqrt(5))"); |
| } |
| }, |
| { |
| name: "atanh computes the inverse hyperbolic tangent and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.atanh, NaN, "if x is NaN, then the result of atanh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.atanh, -1.001, "if x is less than -1, then the result of atanh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.atanh, -2, "if x is less than -1, then the result of atanh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.atanh, -Infinity, "if x is less than -1, then the result of atanh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.atanh, 1.001, "if x is greater than 1, then the result of atanh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.atanh, 2, "if x is greater than 1, then the result of atanh(x) is NaN"); |
| assertFunctionExactlyEqual( NaN, Math.atanh, +Infinity, "if x is greater than 1, then the result of atanh(x) is NaN"); |
| assertFunctionExactlyEqual(-Infinity, Math.atanh, -1, "if x is -1, then the result of atanh(x) is -Infinity"); |
| assertFunctionExactlyEqual(+Infinity, Math.atanh, 1, "if x is 1, then the result of atanh(x) is +Infinity"); |
| assertFunctionExactlyEqual( +0, Math.atanh, +0, "if x is +0, then the result of atanh(x) is +0"); |
| assertFunctionExactlyEqual( -0, Math.atanh, -0, "if x is -0, then the result of atanh(x) is -0"); |
| |
| var atanh05 = Math.log(3) / 2; |
| var atanh025 = Math.log(5/3) / 2; |
| |
| assertFunctionAlmostEqual( atanh05, Math.atanh, 0.5, "atanh(0.5) = 1/2 * ln(1.5 / 0.5)"); |
| assertFunctionAlmostEqual( atanh025, Math.atanh, 0.25, "atanh(0.25) = 1/2 * ln(1.25 / 0.75)"); |
| } |
| }, |
| { |
| name: "hypot computes the square root of the sum of the squares of the arguments and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual2(+Infinity, Math.hypot, +Infinity, 0, "if any argument is +Infinity, then the result of hypot(x,y) is +Infinity"); |
| assertFunctionExactlyEqual2(+Infinity, Math.hypot, 0, +Infinity, "if any argument is +Infinity, then the result of hypot(x,y) is +Infinity"); |
| assertFunctionExactlyEqual2(+Infinity, Math.hypot, -Infinity, 0, "if any argument is -Infinity, then the result of hypot(x,y) is +Infinity"); |
| assertFunctionExactlyEqual2(+Infinity, Math.hypot, 0, -Infinity, "if any argument is -Infinity, then the result of hypot(x,y) is +Infinity"); |
| assertFunctionExactlyEqual2(+Infinity, Math.hypot, +Infinity, NaN, "if any argument is +Infinity, then the result of hypot(x,y) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual2(+Infinity, Math.hypot, NaN, +Infinity, "if any argument is +Infinity, then the result of hypot(x,y) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual2(+Infinity, Math.hypot, -Infinity, NaN, "if any argument is -Infinity, then the result of hypot(x,y) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual2(+Infinity, Math.hypot, NaN, -Infinity, "if any argument is -Infinity, then the result of hypot(x,y) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual2( NaN, Math.hypot, NaN, 0, "if no argument is +/- Infinity, and any argument is NaN, then the result of hypot(x,y) is NaN"); |
| assertFunctionExactlyEqual2( NaN, Math.hypot, 0, NaN, "if no argument is +/- Infinity, and any argument is NaN, then the result of hypot(x,y) is NaN"); |
| assertFunctionExactlyEqual2( +0, Math.hypot, 0, 0, "if all arguments are either +0 or -0, then the result of hypot(x,y) is +0"); |
| assertFunctionExactlyEqual2( +0, Math.hypot, -0, -0, "if all arguments are either +0 or -0, then the result of hypot(x,y) is +0"); |
| |
| assertFunctionExactlyEqual2( 1.4142135623730951e308, Math.hypot, 1e308, 1e308, "hypot(1e308, 1e308) = 1.414e308 and shouldn't cause NaN from premature overflow"); |
| assertFunctionExactlyEqual2(1.4142135623730951e-308, Math.hypot, 1e-308, 1e-308, "hypot(1e-308, 1e-308) = 1.414e-308 and shouldn't cause NaN from premature underflow"); |
| |
| assertFunctionAlmostEqual2( 5, Math.hypot, 3, 4, "hypot(3,4) = 5"); |
| |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, +Infinity, 0, 0, "if any argument is +Infinity, then the result of hypot(x,y,z) is +Infinity"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, 0, +Infinity, 0, "if any argument is +Infinity, then the result of hypot(x,y,z) is +Infinity"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, 0, 0, +Infinity, "if any argument is +Infinity, then the result of hypot(x,y,z) is +Infinity"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, -Infinity, 0, 0, "if any argument is -Infinity, then the result of hypot(x,y,z) is +Infinity"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, 0, -Infinity, 0, "if any argument is -Infinity, then the result of hypot(x,y,z) is +Infinity"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, 0, 0, -Infinity, "if any argument is -Infinity, then the result of hypot(x,y,z) is +Infinity"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, +Infinity, NaN, NaN, "if any argument is +Infinity, then the result of hypot(x,y,z) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, NaN, +Infinity, NaN, "if any argument is +Infinity, then the result of hypot(x,y,z) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, NaN, NaN, +Infinity, "if any argument is +Infinity, then the result of hypot(x,y,z) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, -Infinity, NaN, NaN, "if any argument is -Infinity, then the result of hypot(x,y,z) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, NaN, -Infinity, NaN, "if any argument is -Infinity, then the result of hypot(x,y,z) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual3(+Infinity, Math.hypot, NaN, NaN, -Infinity, "if any argument is -Infinity, then the result of hypot(x,y,z) is +Infinity, even if another argument is NaN"); |
| assertFunctionExactlyEqual3( NaN, Math.hypot, NaN, 0, 0, "if no argument is +/- Infinity, and any argument is NaN, then the result of hypot(x,y,z) is NaN"); |
| assertFunctionExactlyEqual3( NaN, Math.hypot, 0, NaN, 0, "if no argument is +/- Infinity, and any argument is NaN, then the result of hypot(x,y,z) is NaN"); |
| assertFunctionExactlyEqual3( NaN, Math.hypot, 0, 0, NaN, "if no argument is +/- Infinity, and any argument is NaN, then the result of hypot(x,y,z) is NaN"); |
| assertFunctionExactlyEqual3( +0, Math.hypot, 0, 0, 0, "if all arguments are either +0 or -0, then the result of hypot(x,y,z) is +0"); |
| assertFunctionExactlyEqual3( +0, Math.hypot, -0, -0, -0, "if all arguments are either +0 or -0, then the result of hypot(x,y,z) is +0"); |
| |
| assertFunctionExactlyEqual3(1.7320508075688772e+308, Math.hypot, 1e308, 1e308, 1e308, "hypot(1e308, 1e308, 1e308) = 1.732e308 and shouldn't cause NaN from premature overflow"); |
| assertFunctionExactlyEqual3(1.7320508075688772e-308, Math.hypot, 1e-308, 1e-308, 1e-308, "hypot(1e-308, 1e-308, 1e-308) = 1.732e-308 and shouldn't cause NaN from premature underflow"); |
| assertFunctionExactlyEqual3(1.4142135623730951e-308, Math.hypot, 0, 1e-308, 1e-308, "hypot(0, 1e-308, 1e-308) = 1.414e-308 and shouldn't cause NaN from premature underflow (testing NonZeroMin codepath)"); |
| assertFunctionExactlyEqual3(1.4142135623730951e-308, Math.hypot, 1e-308, 0, 1e-308, "hypot(1e-308, 0, 1e-308) = 1.414e-308 and shouldn't cause NaN from premature underflow (testing NonZeroMin codepath)"); |
| assertFunctionExactlyEqual3(1.4142135623730951e-308, Math.hypot, 1e-308, 1e-308, 0, "hypot(1e-308, 1e-308, 0) = 1.414e-308 and shouldn't cause NaN from premature underflow (testing NonZeroMin codepath)"); |
| assertFunctionExactlyEqual3( 1e-308, Math.hypot, 1e-308, 0, 0, "hypot(1e-308, 0, 0) = 1.414e-308 and shouldn't cause NaN from premature underflow (testing NonZeroMin codepath)"); |
| assertFunctionExactlyEqual3( 1e-308, Math.hypot, 0, 1e-308, 0, "hypot(0, 1e-308, 0) = 1.414e-308 and shouldn't cause NaN from premature underflow (testing NonZeroMin codepath)"); |
| assertFunctionExactlyEqual3( 1e-308, Math.hypot, 0, 0, 1e-308, "hypot(0, 0, 1e-308) = 1.414e-308 and shouldn't cause NaN from premature underflow (testing NonZeroMin codepath)"); |
| |
| assertFunctionAlmostEqual3( 7, Math.hypot, 2, 3, 6, "hypot(2,3,6) = 7"); |
| |
| assertFunctionExactlyEqual4( 1.7776388834631178e308, Math.hypot, 1e308, 1e308, 1e308, 4e307, "hypot(1e308, 1e308, 1e308, 4e307) = 1.777e308 and shouldn't cause NaN from premature overflow"); |
| assertFunctionExactlyEqual4( 2e-308, Math.hypot, 1e-308, 1e-308, 1e-308, 1e-308, "hypot(1e-308, 1e-308, 1e-308, 1e-308) = 2e-308 and shouldn't cause NaN from premature underflow"); |
| assertFunctionExactlyEqual4( 1.732050807568877e-308, Math.hypot, 0, 1e-308, 1e-308, 1e-308, "hypot(0, 1e-308, 1e-308, 1e-308) = 1.732e-308 and shouldn't cause NaN from premature underflow "); |
| assertFunctionExactlyEqual4( 1.4142135623730951e-308, Math.hypot, 1e-308, 0, 1e-308, 0, "hypot(1e-308, 0, 1e-308, 0) = 1.414e-308 and shouldn't cause NaN from premature underflow "); |
| assertFunctionExactlyEqual4( 1.4142135623730951e-308, Math.hypot, 1e-308, 1e-308, 0, 0, "hypot(1e-308, 1e-308, 0, 0) = 1.414e-308 and shouldn't cause NaN from premature underflow "); |
| assertFunctionExactlyEqual4( 1e-308, Math.hypot, 1e-308, 0, 0, 0, "hypot(1e-308, 0, 0) = 1.414e-308 and shouldn't cause NaN from premature underflow"); |
| assertFunctionExactlyEqual4( 1.414213562373095e-308, Math.hypot, 0, 1e-308, 0, 1e-308, "hypot(0, 1e-308, 0, 1e-308) = 1.414e-308 and shouldn't cause NaN from premature underflow"); |
| assertFunctionExactlyEqual4( 1.4142135623730951e+308, Math.hypot, 1e308, 0, 0, 1e308, "hypot(1e308, 0, 0, 1e308) = 1.414e+308 and shouldn't cause NaN from premature overflow"); |
| assertFunctionExactlyEqual4( +0, Math.hypot, -0, -0, -0, -0, "hypot(-0, -0, -0, -0) = 0 All zeros positive or negative result in zero"); |
| assertFunctionExactlyEqual4( +0, Math.hypot, 0, -0, 0, -0, "hypot(0, -0, 0, -0) = 0 All zeros positive or negative result in zero"); |
| assertFunctionExactlyEqual4( NaN, Math.hypot, 0, NaN, 1e-308, 0, "hypot(0, NaN, 0, 1e-308) = NaN"); |
| assertFunctionExactlyEqual4( Infinity, Math.hypot, 1e+308, NaN, 1e-308,Infinity, "hypot(1e+308, NaN, 1e-308, Infinity) = Infinity, If any argument is infinity result is infinity"); |
| assertFunctionExactlyEqual4( 1.0000014999988748e-305, Math.hypot, 1e-308, 1e-308, 1e-308, 1e-305, "hypot(1e-308, 1e-308, 1e-308, 1e-305) = 1e-305, and shouldn't cause NaN from premature overflow "); |
| assertFunctionExactlyEqual4( 1.4142135623730951e+308, Math.hypot, 1e-308, 1e+308, 1e-308, 1e+308, "hypot(1e+308, 1e+308, 1e-308, 1e+308) = 1.414e+308 , and shouldn't cause NaN from premature overflow"); |
| |
| assertFunctionExactlyEqual4( 13.950268814614288, Math.hypot, 3.2, -4.8, 9.7, 8.2, "hypot(3.2, -4.8, 9.7, 8.2) = 13.9502"); |
| assertFunctionExactlyEqual4( 25, Math.hypot, 2, 3, 6, 24, "hypot(2, 3, 6, 24) = 25"); |
| assertFunctionExactlyEqual4( 25, Math.hypot, 24, 2, 3, 6, "hypot(24, 2, 3, 6) = 25"); |
| assertFunctionExactlyEqual4( 25, Math.hypot, 2, 24, 3, 6, "hypot(2, 24, 3, 6) = 25"); |
| assertFunctionExactlyEqual4( 25, Math.hypot, 6, 3, 24, 2, "hypot(6, 3, 24, 2) = 25"); |
| |
| assertFunctionExactlyEqual7( 2.6457513110645905e+307, Math.hypot, 1e+307, 1e+307, 1e+307, 1e+307, 1e+307, 1e+307, 1e+307, "hypot(1e+307, ...) = 2.545e+307 and shouldn't cause NaN from premature overflow"); |
| assertFunctionExactlyEqual7( 2.6457513110645904e-308, Math.hypot, 1e-308, 1e-308, 1e-308, 1e-308, 1e-308, 1e-308, 1e-308, "hypot(1e-308, ...) = 2.645e-308, and shouldn't cause NaN from premature underflow"); |
| } |
| }, |
| { |
| name: "trunc computes the integral part of the argument by removing any fractional digits and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.trunc, NaN, "if x is NaN, then the result of trunc(x) is NaN"); |
| assertFunctionExactlyEqual( -0, Math.trunc, -0, "if x is -0, then the result of trunc(x) is -0"); |
| assertFunctionExactlyEqual( +0, Math.trunc, +0, "if x is +0, then the result of trunc(x) is +0"); |
| assertFunctionExactlyEqual(-Infinity, Math.trunc, -Infinity, "if x is -Infinity, then the result of trunc(x) is -Infinity"); |
| assertFunctionExactlyEqual(+Infinity, Math.trunc, +Infinity, "if x is +Infinity, then the result of trunc(x) is +Infinity"); |
| |
| assertFunctionExactlyEqual( +0, Math.trunc, 0.5, "trunc(0.5) = +0"); |
| assertFunctionExactlyEqual( -0, Math.trunc, -0.5, "trunc(-0.5) = -0"); |
| assertFunctionExactlyEqual( 3, Math.trunc, Math.PI, "trunc(pi) = 3"); |
| assertFunctionExactlyEqual( -3, Math.trunc, -Math.PI, "trunc(-pi) = -3"); |
| assertFunctionExactlyEqual( 123, Math.trunc, 123.456, "trunc(123.456) = 123"); |
| } |
| }, |
| { |
| name: "sign computes sign of the argument indicating whether it is positive, negative, or zero and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.sign, NaN, "if x is NaN, then the result of sign(x) is NaN"); |
| assertFunctionExactlyEqual( -0, Math.sign, -0, "if x is -0, then the result of sign(x) is -0"); |
| assertFunctionExactlyEqual( +0, Math.sign, +0, "if x is +0, then the result of sign(x) is +0"); |
| assertFunctionExactlyEqual( -1, Math.sign, -0.001, "if x is negative and not -0, then the result of sign(x) is -1"); |
| assertFunctionExactlyEqual( -1, Math.sign, -1, "if x is negative and not -0, then the result of sign(x) is -1"); |
| assertFunctionExactlyEqual( -1, Math.sign, -200, "if x is negative and not -0, then the result of sign(x) is -1"); |
| assertFunctionExactlyEqual( -1, Math.sign, -Infinity, "if x is negative and not -0, then the result of sign(x) is -1"); |
| assertFunctionExactlyEqual( 1, Math.sign, 0.001, "if x is positive and not +0, then the result of sign(x) is 1"); |
| assertFunctionExactlyEqual( 1, Math.sign, 1, "if x is positive and not +0, then the result of sign(x) is 1"); |
| assertFunctionExactlyEqual( 1, Math.sign, 200, "if x is positive and not +0, then the result of sign(x) is 1"); |
| assertFunctionExactlyEqual( 1, Math.sign, Infinity, "if x is positive and not +0, then the result of sign(x) is 1"); |
| } |
| }, |
| { |
| name: "cbrt computes the cube root and follows spec on special boundary values", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.cbrt, NaN, "if x is NaN, then the result of cbrt(x) is NaN"); |
| assertFunctionExactlyEqual( +0, Math.cbrt, +0, "if x is +0, then the result of cbrt(x) is +0"); |
| assertFunctionExactlyEqual( -0, Math.cbrt, -0, "if x is -0, then the result of cbrt(x) is -0"); |
| assertFunctionExactlyEqual(+Infinity, Math.cbrt, +Infinity, "if x is +Infinity, then the result of cbrt(x) is +Infinity"); |
| assertFunctionExactlyEqual(-Infinity, Math.cbrt, -Infinity, "if x is -Infinity, then the result of cbrt(x) is -Infinity"); |
| |
| assertFunctionAlmostEqual( 1, Math.cbrt, 1, "cbrt(1) = 1"); |
| assertFunctionAlmostEqual( -1, Math.cbrt, -1, "cbrt(-1) = -1"); |
| assertFunctionAlmostEqual( 2, Math.cbrt, 8, "cbrt(8) = 2"); |
| assertFunctionAlmostEqual( -2, Math.cbrt, -8, "cbrt(-8) = -2"); |
| assertFunctionAlmostEqual( 5, Math.cbrt, 125, "cbrt(125) = 5"); |
| assertFunctionAlmostEqual( -5, Math.cbrt, -125, "cbrt(-125) = -5"); |
| } |
| }, |
| { |
| name: "imul computes the multiplication of two unsigned 32 bit integers modulo 2^32", |
| body: function () { |
| function assertFunctionExactlyEqual2ForAllY(expected, fn, x, message) { |
| assertFunctionExactlyEqual2(expected, fn, x, NaN, message + " for all y (y === NaN)"); |
| assertFunctionExactlyEqual2(expected, fn, x, +Infinity, message + " for all y (y === +Infinity)"); |
| assertFunctionExactlyEqual2(expected, fn, x, -Infinity, message + " for all y (y === -Infinity)"); |
| assertFunctionExactlyEqual2(expected, fn, x, +0, message + " for all y (y === +0)"); |
| assertFunctionExactlyEqual2(expected, fn, x, -0, message + " for all y (y === -0)"); |
| assertFunctionExactlyEqual2(expected, fn, x, +0.5, message + " for all y (y === +0.5)"); |
| assertFunctionExactlyEqual2(expected, fn, x, -0.5, message + " for all y (y === -0.5)"); |
| assertFunctionExactlyEqual2(expected, fn, x, +1, message + " for all y (y === +1)"); |
| assertFunctionExactlyEqual2(expected, fn, x, -1, message + " for all y (y === -1)"); |
| assertFunctionExactlyEqual2(expected, fn, x, +1.5, message + " for all y (y === +1.5)"); |
| assertFunctionExactlyEqual2(expected, fn, x, -1.5, message + " for all y (y === -1.5)"); |
| assertFunctionExactlyEqual2(expected, fn, x, +50, message + " for all y (y === +50)"); |
| assertFunctionExactlyEqual2(expected, fn, x, -50, message + " for all y (y === -50)"); |
| assertFunctionExactlyEqual2(expected, fn, x, +12345.67, message + " for all y (y === +12345.67)"); |
| assertFunctionExactlyEqual2(expected, fn, x, -12345.67, message + " for all y (y === -12345.67)"); |
| } |
| |
| assertFunctionExactlyEqual2ForAllY( +0, Math.imul, NaN, "if x is NaN, then the result of imul(x,y) is +0"); |
| assertFunctionExactlyEqual2ForAllY( +0, Math.imul, +0, "if x is +0, then the result of imul(x,y) is +0"); |
| assertFunctionExactlyEqual2ForAllY( +0, Math.imul, -0, "if x is -0, then the result of imul(x,y) is +0"); |
| assertFunctionExactlyEqual2ForAllY( +0, Math.imul, +Infinity, "if x is +Infinity, then the result of imul(x,y) is +0"); |
| assertFunctionExactlyEqual2ForAllY( +0, Math.imul, -Infinity, "if x is -Infinity, then the result of imul(x,y) is +0"); |
| |
| assertFunctionExactlyEqual2( 0, Math.imul, 0, 0, "imul(0,0) is 0"); |
| assertFunctionExactlyEqual2( 0, Math.imul, 0, 1, "imul(0,0) is 0"); |
| assertFunctionExactlyEqual2( 0, Math.imul, 1, 0, "imul(0,0) is 0"); |
| assertFunctionExactlyEqual2( 1, Math.imul, 1, 1, "imul(0,0) is 0"); |
| assertFunctionExactlyEqual2( 6, Math.imul, 2, 3, "imul(0,0) is 0"); |
| assertFunctionExactlyEqual2( -8, Math.imul, 4, -2, "imul(0,0) is 0"); |
| assertFunctionExactlyEqual2( 1024, Math.imul, 32, 32, "imul(0,0) is 0"); |
| assertFunctionExactlyEqual2( 0, Math.imul, 65536, 65536, "imul(2^16,2^16) is 0 because imul is modulo 2^32"); |
| assertFunctionExactlyEqual2(-2147483648, Math.imul, 32768, 65536, "imul(2^15,2^16) is -2^31 because imul is modulo 2^32 and subtracts 2^31 if the value would be greater than or equal to 2^31"); |
| assertFunctionExactlyEqual2(-2147418112, Math.imul, 32769, 65536, "imul(2^15 + 1,2^16) is -2^31 + 65536 because imul is modulo 2^32 and subtracts 2^31 if the value would be greater than or equal to 2^31"); |
| } |
| }, |
| { |
| name: "clz returns the number of leading zero bits of the unsigned 32 bit integer representation of the this argument", |
| body: function () { |
| assertFunctionExactlyEqual(32, Math.clz32, 0x00000000, "32 leading zero bits in the uint32 value 0x00000000"); |
| assertFunctionExactlyEqual(31, Math.clz32, 0x00000001, "31 leading zero bits in the uint32 value 0x00000001"); |
| assertFunctionExactlyEqual(30, Math.clz32, 0x00000002, "30 leading zero bits in the uint32 value 0x00000002"); |
| assertFunctionExactlyEqual(29, Math.clz32, 0x00000004, "29 leading zero bits in the uint32 value 0x00000004"); |
| assertFunctionExactlyEqual(28, Math.clz32, 0x00000008, "28 leading zero bits in the uint32 value 0x00000008"); |
| assertFunctionExactlyEqual(27, Math.clz32, 0x00000010, "27 leading zero bits in the uint32 value 0x00000010"); |
| assertFunctionExactlyEqual(26, Math.clz32, 0x00000020, "26 leading zero bits in the uint32 value 0x00000020"); |
| assertFunctionExactlyEqual(25, Math.clz32, 0x00000040, "25 leading zero bits in the uint32 value 0x00000040"); |
| assertFunctionExactlyEqual(24, Math.clz32, 0x00000080, "24 leading zero bits in the uint32 value 0x00000080"); |
| assertFunctionExactlyEqual(23, Math.clz32, 0x00000100, "23 leading zero bits in the uint32 value 0x00000100"); |
| assertFunctionExactlyEqual(22, Math.clz32, 0x00000200, "22 leading zero bits in the uint32 value 0x00000200"); |
| assertFunctionExactlyEqual(21, Math.clz32, 0x00000400, "21 leading zero bits in the uint32 value 0x00000400"); |
| assertFunctionExactlyEqual(20, Math.clz32, 0x00000800, "20 leading zero bits in the uint32 value 0x00000800"); |
| assertFunctionExactlyEqual(19, Math.clz32, 0x00001000, "19 leading zero bits in the uint32 value 0x00001000"); |
| assertFunctionExactlyEqual(18, Math.clz32, 0x00002000, "18 leading zero bits in the uint32 value 0x00002000"); |
| assertFunctionExactlyEqual(17, Math.clz32, 0x00004000, "17 leading zero bits in the uint32 value 0x00004000"); |
| assertFunctionExactlyEqual(16, Math.clz32, 0x00008000, "16 leading zero bits in the uint32 value 0x00008000"); |
| assertFunctionExactlyEqual(15, Math.clz32, 0x00010000, "15 leading zero bits in the uint32 value 0x00010000"); |
| assertFunctionExactlyEqual(14, Math.clz32, 0x00020000, "14 leading zero bits in the uint32 value 0x00020000"); |
| assertFunctionExactlyEqual(13, Math.clz32, 0x00040000, "13 leading zero bits in the uint32 value 0x00040000"); |
| assertFunctionExactlyEqual(12, Math.clz32, 0x00080000, "12 leading zero bits in the uint32 value 0x00080000"); |
| assertFunctionExactlyEqual(11, Math.clz32, 0x00100000, "11 leading zero bits in the uint32 value 0x00100000"); |
| assertFunctionExactlyEqual(10, Math.clz32, 0x00200000, "10 leading zero bits in the uint32 value 0x00200000"); |
| assertFunctionExactlyEqual( 9, Math.clz32, 0x00400000, "9 leading zero bits in the uint32 value 0x00400000"); |
| assertFunctionExactlyEqual( 8, Math.clz32, 0x00800000, "8 leading zero bits in the uint32 value 0x00800000"); |
| assertFunctionExactlyEqual( 7, Math.clz32, 0x01000000, "7 leading zero bits in the uint32 value 0x01000000"); |
| assertFunctionExactlyEqual( 6, Math.clz32, 0x02000000, "6 leading zero bits in the uint32 value 0x02000000"); |
| assertFunctionExactlyEqual( 5, Math.clz32, 0x04000000, "5 leading zero bits in the uint32 value 0x04000000"); |
| assertFunctionExactlyEqual( 4, Math.clz32, 0x08000000, "4 leading zero bits in the uint32 value 0x08000000"); |
| assertFunctionExactlyEqual( 3, Math.clz32, 0x10000000, "3 leading zero bits in the uint32 value 0x10000000"); |
| assertFunctionExactlyEqual( 2, Math.clz32, 0x20000000, "2 leading zero bits in the uint32 value 0x20000000"); |
| assertFunctionExactlyEqual( 1, Math.clz32, 0x40000000, "1 leading zero bit in the uint32 value 0x40000000"); |
| assertFunctionExactlyEqual( 0, Math.clz32, 0x80000000, "0 leading zero bits in the uint32 value 0x80000000"); |
| |
| // quick random sampling to ensure values with more than one "one" bits still produce the correct result |
| assertFunctionExactlyEqual(28, Math.clz32, 0x0000000A, "28 leading zero bits in the uint32 value 0x0000000A, same as 0x00000008"); |
| assertFunctionExactlyEqual(17, Math.clz32, 0x00007ABC, "17 leading zero bits in the uint32 value 0x00007ABC, same as 0x00004000"); |
| assertFunctionExactlyEqual( 3, Math.clz32, 0x10380FE1, "3 leading zero bits in the uint32 value 0x10380FE1, same as 0x10000000"); |
| |
| // The argument is converted to a uint32 via the ToUint32 algorithm, so all objects work |
| assertFunctionExactlyEqual(32, Math.clz32, undefined, "Undefined converts to +0 therefore 32 leading zero bits"); |
| assertFunctionExactlyEqual(32, Math.clz32, "hello", "Non-number string converts to +0 therefore 32 leading zero bits"); |
| assertFunctionExactlyEqual( 2, Math.clz32, "0x20000000", "Number string converts to that number therefore however many leading zero bits"); |
| var o = { valueOf: function () { return 0x00800000; } }; |
| assertFunctionExactlyEqual( 8, Math.clz32, o, "Object with valueOf method converts to result of that method therefore however many leading zero bits"); |
| } |
| }, |
| { |
| name: "fround converts 64-bit float to 32-bit float and back to 64-bit float", |
| body: function () { |
| assertFunctionExactlyEqual( NaN, Math.fround, NaN, "if x is NaN, then the result of fround(x) is NaN"); |
| assertFunctionExactlyEqual(+Infinity, Math.fround, +Infinity, "if x is +Infinity, then the result of fround(x) is +Infinity"); |
| assertFunctionExactlyEqual(-Infinity, Math.fround, -Infinity, "if x is -Infinity, then the result of fround(x) is -Infinity"); |
| assertFunctionExactlyEqual( +0, Math.fround, +0, "if x is +0, then the result of fround(x) is +0"); |
| assertFunctionExactlyEqual( -0, Math.fround, -0, "if x is -0, then the result of fround(x) is -0"); |
| assertFunctionExactlyEqual( +1, Math.fround, +1, "if x is +1, then the result of fround(x) is +1"); |
| assertFunctionExactlyEqual( -1, Math.fround, -1, "if x is -1, then the result of fround(x) is -1"); |
| assertFunctionExactlyEqual( +2, Math.fround, +2, "if x is +2, then the result of fround(x) is +2"); |
| assertFunctionExactlyEqual( -2, Math.fround, -2, "if x is -2, then the result of fround(x) is -2"); |
| assertFunctionExactlyEqual( +5, Math.fround, +5, "if x is +5, then the result of fround(x) is +5"); |
| assertFunctionExactlyEqual( -5, Math.fround, -5, "if x is -5, then the result of fround(x) is -5"); |
| assertFunctionExactlyEqual( +100, Math.fround, +100, "if x is +100, then the result of fround(x) is +100"); |
| assertFunctionExactlyEqual( -100, Math.fround, -100, "if x is -100, then the result of fround(x) is -100"); |
| assertFunctionExactlyEqual( +0.5, Math.fround, +0.5, "if x is +0.5, then the result of fround(x) is +0.5"); |
| assertFunctionExactlyEqual( -0.5, Math.fround, -0.5, "if x is -0.5, then the result of fround(x) is -0.5"); |
| |
| let testcase = [ |
| // numbers between zero and one |
| [0.5995356650091708 , 0.5995356440544128 ], |
| [0.4388806028291583 , 0.43888059258461 ], |
| [0.05652953824028373 , 0.056529536843299866 ], |
| [0.8834999229293317 , 0.8834999203681946 ], |
| [0.19564732676371932 , 0.19564732909202576 ], |
| [0.04695801460184157 , 0.046958014369010925 ], |
| [0.995549641083926 , 0.9955496191978455 ], |
| [0.5965264535043389 , 0.5965264439582825 ], |
| [0.3384522853884846 , 0.3384522795677185 ], |
| [0.4793784348294139 , 0.47937843203544617 ], |
| |
| // large integers |
| [968719029287650 , 968719001976832 ], |
| [612872438100595 , 612872438677504 ], |
| [986007985043197 , 986007990173696 ], |
| [229849530517651 , 229849536921600 ], |
| [1069224778058320 , 1069224793473024 ], |
| [404824585745150 , 404824591958016 ], |
| [980853506006873 , 980853492547584 ], |
| [156784970534624 , 156784962568192 ], |
| [416562781028203 , 416562771132416 ], |
| [724128106542317 , 724128130662400 ], |
| |
| // arbitrary numbers |
| [6785.904748927644 , 6785.90478515625 ], |
| [5.585741676777502 , 5.5857415199279785 ], |
| [0.1787555584523126 , 0.17875555157661438 ], |
| [45167.42179931141 , 45167.421875 ], |
| [53.97847279046722 , 53.97847366333008 ], |
| [708731082.0651336 , 708731072 ], |
| [786033.2273395439 , 786033.25 ], |
| [134428002986767.81 , 134428005236736 ], |
| [10598756866706 , 10598756646912 ], |
| [2316.058639210134 , 2316.05859375 ], |
| ]; |
| for (let i=0; i < testcase.length; i++) { |
| assertFunctionExactlyEqual( testcase[i][1], Math.fround, testcase[i][0], "if x is "+testcase[i][0]+", then the result of fround(x) is "+testcase[i][1]); |
| } |
| |
| // Test against type specialization bugs |
| // -bgjit- -maxinterpretcount:1 -maxsimplejitruncount:2 |
| function fround_testsub() { |
| protoObj2.prop0 = Math.fround(1); |
| return protoObj2.prop0; |
| } |
| let obj2={}; |
| let protoObj2 = Object.create(obj2); |
| |
| fround_testsub(); |
| fround_testsub(); |
| fround_testsub(); // ok till this point |
| assert.areEqual( 1, fround_testsub(), "Math.fround() expects both input and output type specialized to float64") ; |
| } |
| }, |
| ]; |
| |
| testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" }); |