tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

testFloat32-correctness.js (8015B)


      1 setJitCompilerOption("ion.warmup.trigger", 50);
      2 
      3 var f32 = new Float32Array(10);
      4 
      5 function test(setup, f) {
      6    if (f === undefined) {
      7        f = setup;
      8        setup = function(){};
      9    }
     10    setup();
     11    for(var n = 200; n; --n) {
     12        f();
     13    }
     14 }
     15 
     16 // Basic arithmetic
     17 function setupBasicArith() {
     18    f32[0] = -Infinity;
     19    f32[1] = -1;
     20    f32[2] = -0;
     21    f32[3] = 0;
     22    f32[4] = 1.337;
     23    f32[5] = 42;
     24    f32[6] = Infinity;
     25    f32[7] = NaN;
     26 }
     27 function basicArith() {
     28    for (var i = 0; i < 7; ++i) {
     29        var opf = Math.fround(f32[i] + f32[i+1]);
     30        var opd = (1 / (1 / f32[i])) + f32[i+1];
     31        assertFloat32(opf, true);
     32        assertFloat32(opd, false);
     33        assertEq(opf, Math.fround(opd));
     34 
     35        opf = Math.fround(f32[i] - f32[i+1]);
     36        opd = (1 / (1 / f32[i])) - f32[i+1];
     37        assertFloat32(opf, true);
     38        assertFloat32(opd, false);
     39        assertEq(opf, Math.fround(opd));
     40 
     41        opf = Math.fround(f32[i] * f32[i+1]);
     42        opd = (1 / (1 / f32[i])) * f32[i+1];
     43        assertFloat32(opf, true);
     44        assertFloat32(opd, false);
     45        assertEq(opf, Math.fround(opd));
     46 
     47        opf = Math.fround(f32[i] / f32[i+1]);
     48        opd = (1 / (1 / f32[i])) / f32[i+1];
     49        assertFloat32(opf, true);
     50        assertFloat32(opd, false);
     51        assertEq(opf, Math.fround(opd));
     52    }
     53 }
     54 test(setupBasicArith, basicArith);
     55 
     56 // MAbs
     57 function setupAbs() {
     58    f32[0] = -0;
     59    f32[1] = 0;
     60    f32[2] = -3.14159;
     61    f32[3] = 3.14159;
     62    f32[4] = -Infinity;
     63    f32[5] = Infinity;
     64    f32[6] = NaN;
     65 }
     66 function abs() {
     67    for(var i = 0; i < 7; ++i) {
     68        assertEq( Math.fround(Math.abs(f32[i])), Math.abs(f32[i]) );
     69    }
     70 }
     71 test(setupAbs, abs);
     72 
     73 // MSqrt
     74 function setupSqrt() {
     75    f32[0] = 0;
     76    f32[1] = 1;
     77    f32[2] = 4;
     78    f32[3] = -1;
     79    f32[4] = Infinity;
     80    f32[5] = NaN;
     81    f32[6] = 13.37;
     82 }
     83 function sqrt() {
     84    for(var i = 0; i < 7; ++i) {
     85        var sqrtf = Math.fround(Math.sqrt(f32[i]));
     86        var sqrtd = 1 + Math.sqrt(f32[i]) - 1; // force no float32 by chaining arith ops
     87        assertEq( sqrtf, Math.fround(sqrtd) );
     88    }
     89 }
     90 test(setupSqrt, sqrt);
     91 
     92 // MMinMax
     93 function setupMinMax() {
     94    f32[0] = -0;
     95    f32[1] = 0;
     96    f32[2] = 1;
     97    f32[3] = 4;
     98    f32[4] = -1;
     99    f32[5] = Infinity;
    100    f32[6] = NaN;
    101    f32[7] = 13.37;
    102    f32[8] = -Infinity;
    103    f32[9] = Math.pow(2,31) - 1;
    104 }
    105 function minMax() {
    106    for(var i = 0; i < 9; ++i) {
    107        for(var j = 0; j < 9; j++) {
    108            var minf = Math.fround(Math.min(f32[i], f32[j]));
    109            var mind = 1 / (1 / Math.min(f32[i], f32[j])); // force no float32 by chaining arith ops
    110            assertFloat32(minf, true);
    111            assertFloat32(mind, false);
    112            assertEq( minf, Math.fround(mind) );
    113 
    114            var maxf = Math.fround(Math.max(f32[i], f32[j]));
    115            var maxd = 1 / (1 / Math.max(f32[i], f32[j])); // force no float32 by chaining arith ops
    116            assertFloat32(maxf, true);
    117            assertFloat32(maxd, false);
    118            assertEq( maxf, Math.fround(maxd) );
    119        }
    120    }
    121 }
    122 test(setupMinMax, minMax);
    123 
    124 // MTruncateToInt32
    125 // The only way to get a MTruncateToInt32 with a Float32 input is to use Math.imul
    126 function setupTruncateToInt32() {
    127    f32[0] = -1;
    128    f32[1] = 4;
    129    f32[2] = 5.13;
    130 }
    131 function truncateToInt32() {
    132    assertEq( Math.imul(f32[0], f32[1]), Math.imul(-1, 4) );
    133    assertEq( Math.imul(f32[1], f32[2]), Math.imul(4, 5) );
    134 }
    135 test(setupTruncateToInt32, truncateToInt32);
    136 
    137 // MCompare
    138 function comp() {
    139    for(var i = 0; i < 9; ++i) {
    140        assertEq( f32[i] < f32[i+1], true );
    141    }
    142 }
    143 function setupComp() {
    144    f32[0] = -Infinity;
    145    f32[1] = -1;
    146    f32[2] = -0.01;
    147    f32[3] = 0;
    148    f32[4] = 0.01;
    149    f32[5] = 1;
    150    f32[6] = 10;
    151    f32[7] = 13.37;
    152    f32[8] = 42;
    153    f32[9] = Infinity;
    154 }
    155 test(setupComp, comp);
    156 
    157 // MNot
    158 function setupNot() {
    159    f32[0] = -0;
    160    f32[1] = 0;
    161    f32[2] = 1;
    162    f32[3] = NaN;
    163    f32[4] = Infinity;
    164    f32[5] = 42;
    165    f32[6] = -23;
    166 }
    167 function not() {
    168    assertEq( !f32[0], true );
    169    assertEq( !f32[1], true );
    170    assertEq( !f32[2], false );
    171    assertEq( !f32[3], true );
    172    assertEq( !f32[4], false );
    173    assertEq( !f32[5], false );
    174    assertEq( !f32[6], false );
    175 }
    176 test(setupNot, not);
    177 
    178 // MToNumberInt32
    179 var str = "can haz cheezburger? okthxbye;";
    180 function setupToInt32() {
    181    f32[0] = 0;
    182    f32[1] = 1;
    183    f32[2] = 2;
    184    f32[3] = 4;
    185    f32[4] = 5;
    186 }
    187 function testToInt32() {
    188    assertEq(str[f32[0]], 'c');
    189    assertEq(str[f32[1]], 'a');
    190    assertEq(str[f32[2]], 'n');
    191    assertEq(str[f32[3]], 'h');
    192    assertEq(str[f32[4]], 'a');
    193 }
    194 test(setupToInt32, testToInt32);
    195 
    196 function setupBailoutToInt32() {
    197    f32[0] = .5;
    198 }
    199 function testBailoutToInt32() {
    200    assertEq(typeof str[f32[0]], 'undefined');
    201 }
    202 test(setupBailoutToInt32, testBailoutToInt32);
    203 
    204 // MMath (no trigo - see also testFloat32-trigo.js
    205 function assertNear(a, b) {
    206    var r = (a != a && b != b) || Math.abs(a-b) < 1e-1 || a === b;
    207    if (!r) {
    208        print('Precision error: ');
    209        print(new Error().stack);
    210        print('Got', a, ', expected near', b);
    211        assertEq(false, true);
    212    }
    213 }
    214 
    215 function setupOtherMath() {
    216    setupComp();
    217    f32[8] = 4.2;
    218 }
    219 function otherMath() {
    220    for (var i = 0; i < 9; ++i) {
    221        assertNear(Math.fround(Math.exp(f32[i])), Math.exp(f32[i]));
    222        assertNear(Math.fround(Math.log(f32[i])), Math.log(f32[i]));
    223    }
    224 };
    225 test(setupOtherMath, otherMath);
    226 
    227 function setupFloor() {
    228    f32[0] = -5.5;
    229    f32[1] = -0.5;
    230    f32[2] = 0;
    231    f32[3] = 1.5;
    232 }
    233 function setupFloorDouble() {
    234    f32[4] = NaN;
    235    f32[5] = -0;
    236    f32[6] = Infinity;
    237    f32[7] = -Infinity;
    238    f32[8] = Math.pow(2,31); // too big to fit into a int
    239 }
    240 function testFloor() {
    241    for (var i = 0; i < 4; ++i) {
    242        var f = Math.floor(f32[i]);
    243        assertFloat32(f, false); // f is an int32
    244 
    245        var g = Math.floor(-0 + f32[i]);
    246        assertFloat32(g, false);
    247 
    248        assertEq(f, g);
    249    }
    250 }
    251 function testFloorDouble() {
    252    for (var i = 4; i < 9; ++i) {
    253        var f = Math.fround(Math.floor(f32[i]));
    254        assertFloat32(f, true);
    255 
    256        var g = Math.floor(-0 + f32[i]);
    257        assertFloat32(g, false);
    258 
    259        assertEq(f, g);
    260    }
    261 }
    262 test(setupFloor, testFloor);
    263 test(setupFloorDouble, testFloorDouble);
    264 
    265 function setupRound() {
    266    f32[0] = -5.5;
    267    f32[1] = -0.6;
    268    f32[2] = 1.5;
    269    f32[3] = 1;
    270 }
    271 function setupRoundDouble() {
    272    f32[4] = NaN;
    273    f32[5] = -0.49;          // rounded to -0
    274    f32[6] = Infinity;
    275    f32[7] = -Infinity;
    276    f32[8] = Math.pow(2,31); // too big to fit into a int
    277    f32[9] = -0;
    278 }
    279 function testRound() {
    280    for (var i = 0; i < 4; ++i) {
    281        var r32 = Math.round(f32[i]);
    282        assertFloat32(r32, false); // r32 is an int32
    283 
    284        var r64 = Math.round(-0 + f32[i]);
    285        assertFloat32(r64, false);
    286 
    287        assertEq(r32, r64);
    288    }
    289 }
    290 function testRoundDouble() {
    291    for (var i = 4; i < 10; ++i) {
    292        var r32 = Math.fround(Math.round(f32[i]));
    293        assertFloat32(r32, true);
    294 
    295        var r64 = Math.round(-0 + f32[i]);
    296        assertFloat32(r64, false);
    297 
    298        assertEq(r32, r64);
    299    }
    300 }
    301 test(setupRound, testRound);
    302 test(setupRoundDouble, testRoundDouble);
    303 
    304 function setupCeil() {
    305    f32[0] = -5.5;
    306    f32[1] = -1.5;
    307    f32[2] = 0;
    308    f32[3] = 1.5;
    309 }
    310 function setupCeilDouble() {
    311    f32[4] = NaN;
    312    f32[5] = -0;
    313    f32[6] = Infinity;
    314    f32[7] = -Infinity;
    315    f32[8] = Math.pow(2,31); // too big to fit into a int
    316 }
    317 function testCeil() {
    318    for(var i = 0; i < 2; ++i) {
    319        var f = Math.ceil(f32[i]);
    320        assertFloat32(f, false);
    321 
    322        var g = Math.ceil(-0 + f32[i]);
    323        assertFloat32(g, false);
    324 
    325        assertEq(f, g);
    326    }
    327 }
    328 function testCeilDouble() {
    329    for(var i = 4; i < 9; ++i) {
    330        var f = Math.fround(Math.ceil(f32[i]));
    331        assertFloat32(f, true);
    332 
    333        var g = Math.ceil(-0 + f32[i]);
    334        assertFloat32(g, false);
    335 
    336        assertEq(f, g);
    337    }
    338 }
    339 test(setupCeil, testCeil);
    340 test(setupCeilDouble, testCeilDouble);