/* * ToUint32() (E5 Section 9.6). * * Indirect testing using '>>>' (E5 Section 11.7.3): "x >>> 0" is equivalent * to ToUint32(x). ToUint32() first coerces with ToNumber(), so that is noted * in the cases. */ function touint32(x) { return x >>> 0; } function zeroSign(x) { if (x !== 0) { return 'nz'; } if (1 / x > 0) { return 'pos'; } else { return 'neg'; } } function test(x) { var t = touint32(x); print(t, zeroSign(t)); } /*=== 0 pos ===*/ // ToNumber(undefined) -> NaN -> +0 test(undefined); /*=== 0 pos ===*/ // ToNumber(null) -> +0 -> +0 test(null); /*=== 1 nz 0 pos ===*/ // ToNumber(true) -> 1 -> 1 test(true); // Tonumber(false) -> +0 -> +0 test(false); /*=== 0 pos 0 pos 0 pos 0 pos 0 pos ===*/ // ToNumber(NaN) -> NaN -> +0 test(NaN); // ToNumber(+0) -> +0 -> +0 test(+0); // ToNumber(-0) -> -0 -> +0 test(-0); // ToNumber(+Infinity) -> +Infinity -> +0 test(Number.POSITIVE_INFINITY); // ToNumber(-Infinity) -> -Infinity -> +0 test(Number.NEGATIVE_INFINITY); /*=== 123 nz 4294967173 nz 0 pos 0 pos 0 pos 0 pos 0 pos 0 pos 0 pos 1410065408 nz ===*/ /* ToNumber() string coercion, E5 Section 9.3.1 */ test("123"); test("-123"); test("+0"); test("-0"); test("Infinity"); test("+Infinity"); test("-Infinity"); test("NaN"); // "NaN" does not parse -> results in NaN number -> +0 test("NaY"); // same case test("1e10"); // larger than 32-bit, fits in 53 bits of double /* FIXME: object coercion */ /*=== 0 pos 1 nz 4294967295 nz 2 nz 4294967295 nz 0 pos 2 nz ===*/ /* A couple of modulo tests */ test(4294967296); test(4294967297); test(-1); // --> 0xffffffffU test(-4294967294); // +2 test(9007199254740991); // (2^53 - 1) % (2^32) --> 4294967295 test(9007199254740992); // (2^53) % (2^32) --> 0 test(9007199254740994); // (2^53 + 2) % (2^32) --> 2 (Note: 2^53+1 not representable) /*=== 3 nz 4294967293 nz ===*/ /* Rounding * * Positive numbers: x -> floor(x) e.g. 3.4 -> 3 * Negative numbers: -x -> -floor(x) e.g. -3.4 -> -3 (not -4) */ test(3.4); // -> 3 -> 3 test(-3.4); // -> -3 -> (2^32) - 3