// These tests have been separated, for several reasons:
// - If we try to run them in a loop (i.e. running through all values in the array),
// it doesn't get Ion compiled because of the size of the overall function.
// - If we try to make, for each Math function, a closure that tests all values, the
// order of running functions has an influence on whether the tests pass or fail (due
// to bailouts).
//
// These tests have been generated by a Python script.
//
setJitCompilerOption("ion.usecount.trigger", 50);

// MMath
function repeat(f) {
    for (var i = 200; i; i--) {
        f();
    }
}

function assertNear(a, b) {
    var r = (a != a && b != b) || Math.abs(a-b) < 1e-7 || a === b;
    if (!r) {
        print('Precision error: ');
        print(new Error().stack);
        print('Got', a, ', expected near', b);
        assertEq(false, true);
    }
}

var trigoInputs = [0, Math.PI / 3, Math.PI, Math.PI * 3 / 4, 1, 1/3, -.5, NaN];
var f32 = new Float32Array(8);
for(var i = 0; i < trigoInputs.length; i++) {
    f32[i] = trigoInputs[i];
}

function testcos () {
        var r32, r64;

        r32 = Math.fround(Math.cos(f32[0]));
        assertFloat32(r32, true);
        r64 = Math.cos(f32[0]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.cos(f32[1]));
        assertFloat32(r32, true);
        r64 = Math.cos(f32[1]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.cos(f32[2]));
        assertFloat32(r32, true);
        r64 = Math.cos(f32[2]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.cos(f32[3]));
        assertFloat32(r32, true);
        r64 = Math.cos(f32[3]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.cos(f32[4]));
        assertFloat32(r32, true);
        r64 = Math.cos(f32[4]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.cos(f32[5]));
        assertFloat32(r32, true);
        r64 = Math.cos(f32[5]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.cos(f32[6]));
        assertFloat32(r32, true);
        r64 = Math.cos(f32[6]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.cos(f32[7]));
        assertFloat32(r32, true);
        r64 = Math.cos(f32[7]);
        assertFloat32(r64, false);
        assertNear(r32, r64);
}
repeat(testcos);
function testacos () {
        var r32, r64;

        r32 = Math.fround(Math.acos(f32[0]));
        assertFloat32(r32, true);
        r64 = Math.acos(f32[0]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.acos(f32[1]));
        assertFloat32(r32, true);
        r64 = Math.acos(f32[1]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.acos(f32[2]));
        assertFloat32(r32, true);
        r64 = Math.acos(f32[2]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.acos(f32[3]));
        assertFloat32(r32, true);
        r64 = Math.acos(f32[3]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.acos(f32[4]));
        assertFloat32(r32, true);
        r64 = Math.acos(f32[4]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.acos(f32[5]));
        assertFloat32(r32, true);
        r64 = Math.acos(f32[5]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.acos(f32[6]));
        assertFloat32(r32, true);
        r64 = Math.acos(f32[6]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.acos(f32[7]));
        assertFloat32(r32, true);
        r64 = Math.acos(f32[7]);
        assertFloat32(r64, false);
        assertNear(r32, r64);
}
repeat(testacos);
function testsin () {
        var r32, r64;

        r32 = Math.fround(Math.sin(f32[0]));
        assertFloat32(r32, true);
        r64 = Math.sin(f32[0]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.sin(f32[1]));
        assertFloat32(r32, true);
        r64 = Math.sin(f32[1]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.sin(f32[2]));
        assertFloat32(r32, true);
        r64 = Math.sin(f32[2]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.sin(f32[3]));
        assertFloat32(r32, true);
        r64 = Math.sin(f32[3]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.sin(f32[4]));
        assertFloat32(r32, true);
        r64 = Math.sin(f32[4]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.sin(f32[5]));
        assertFloat32(r32, true);
        r64 = Math.sin(f32[5]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.sin(f32[6]));
        assertFloat32(r32, true);
        r64 = Math.sin(f32[6]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.sin(f32[7]));
        assertFloat32(r32, true);
        r64 = Math.sin(f32[7]);
        assertFloat32(r64, false);
        assertNear(r32, r64);
}
repeat(testsin);
function testasin () {
        var r32, r64;

        r32 = Math.fround(Math.asin(f32[0]));
        assertFloat32(r32, true);
        r64 = Math.asin(f32[0]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.asin(f32[1]));
        assertFloat32(r32, true);
        r64 = Math.asin(f32[1]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.asin(f32[2]));
        assertFloat32(r32, true);
        r64 = Math.asin(f32[2]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.asin(f32[3]));
        assertFloat32(r32, true);
        r64 = Math.asin(f32[3]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.asin(f32[4]));
        assertFloat32(r32, true);
        r64 = Math.asin(f32[4]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.asin(f32[5]));
        assertFloat32(r32, true);
        r64 = Math.asin(f32[5]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.asin(f32[6]));
        assertFloat32(r32, true);
        r64 = Math.asin(f32[6]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.asin(f32[7]));
        assertFloat32(r32, true);
        r64 = Math.asin(f32[7]);
        assertFloat32(r64, false);
        assertNear(r32, r64);
}
repeat(testasin);
function testtan () {
        var r32, r64;

        r32 = Math.fround(Math.tan(f32[0]));
        assertFloat32(r32, true);
        r64 = Math.tan(f32[0]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.tan(f32[1]));
        assertFloat32(r32, true);
        r64 = Math.tan(f32[1]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.tan(f32[2]));
        assertFloat32(r32, true);
        r64 = Math.tan(f32[2]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.tan(f32[3]));
        assertFloat32(r32, true);
        r64 = Math.tan(f32[3]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.tan(f32[4]));
        assertFloat32(r32, true);
        r64 = Math.tan(f32[4]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.tan(f32[5]));
        assertFloat32(r32, true);
        r64 = Math.tan(f32[5]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.tan(f32[6]));
        assertFloat32(r32, true);
        r64 = Math.tan(f32[6]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.tan(f32[7]));
        assertFloat32(r32, true);
        r64 = Math.tan(f32[7]);
        assertFloat32(r64, false);
        assertNear(r32, r64);
}
repeat(testtan);
function testatan () {
        var r32, r64;

        r32 = Math.fround(Math.atan(f32[0]));
        assertFloat32(r32, true);
        r64 = Math.atan(f32[0]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.atan(f32[1]));
        assertFloat32(r32, true);
        r64 = Math.atan(f32[1]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.atan(f32[2]));
        assertFloat32(r32, true);
        r64 = Math.atan(f32[2]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.atan(f32[3]));
        assertFloat32(r32, true);
        r64 = Math.atan(f32[3]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.atan(f32[4]));
        assertFloat32(r32, true);
        r64 = Math.atan(f32[4]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.atan(f32[5]));
        assertFloat32(r32, true);
        r64 = Math.atan(f32[5]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.atan(f32[6]));
        assertFloat32(r32, true);
        r64 = Math.atan(f32[6]);
        assertFloat32(r64, false);
        assertNear(r32, r64);

        r32 = Math.fround(Math.atan(f32[7]));
        assertFloat32(r32, true);
        r64 = Math.atan(f32[7]);
        assertFloat32(r64, false);
        assertNear(r32, r64);
}
repeat(testatan);
