mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
914 lines
23 KiB
914 lines
23 KiB
/*
|
|
* parseInt() tests
|
|
*
|
|
* parseInt() must have "mathematically exact" results for any supported
|
|
* power of two radix (2, 4, 8, 16, 32). For instance, parsing the base-8
|
|
* representation of 2**256 must yield the exact IEEE double value. This
|
|
* is easy for base two radixes. However, the same property is required
|
|
* also for base 10 (though not for other bases), which is tricky.
|
|
*/
|
|
|
|
var WHITESPACE_CODEPOINTS = [
|
|
// from WhiteSpace production
|
|
0x0009, // <TAB>
|
|
0x000B, // <VT>
|
|
0x000C, // <FF>
|
|
0x0020, // <SP>
|
|
0x00A0, // <NBSP>
|
|
0xFEFF, // <BOM>
|
|
|
|
// WhiteSpace production also has <USP>, which means any other Unicode
|
|
// space separator (category Zs), which needs to be checked from (up to
|
|
// date) Unicode data. The WhiteSpace-Z.txt file, created as part of
|
|
// the build, currently contains (duplicates eliminated):
|
|
|
|
// 0x0020, // 0020;SPACE;Zs;0;WS;;;;;N;;;;;
|
|
// 0x00A0, // 00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;
|
|
0x1680, // 1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;
|
|
0x180E, // 180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;;
|
|
0x2000, // 2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;
|
|
0x2001, // 2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;
|
|
0x2002, // 2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
|
|
0x2003, // 2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
|
|
0x2004, // 2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
|
|
0x2005, // 2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
|
|
0x2006, // 2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
|
|
0x2007, // 2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;
|
|
0x2008, // 2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
|
|
0x2009, // 2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
|
|
0x200A, // 200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
|
|
// 0x2028, // 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;;
|
|
// 0x2029, // 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;;
|
|
0x202F, // 202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;
|
|
0x205F, // 205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
|
|
0x3000, // 3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;
|
|
|
|
// from LineTerminator production
|
|
0x000a, // <LF>
|
|
0x000d, // <CR>
|
|
0x2028, // <LS>
|
|
0x2029, // <PS>
|
|
];
|
|
|
|
// indirect eval -> this is bound to the global object, E5 Section 10.4.2, step 1.a.
|
|
var g = (function () { var e = eval; return e('this'); } )();
|
|
|
|
/*===
|
|
basic tests
|
|
NaN
|
|
123
|
|
51966
|
|
65
|
|
58798832
|
|
===*/
|
|
|
|
/* parseInt: some very basic cases */
|
|
|
|
print('basic tests');
|
|
|
|
try {
|
|
print(g.parseInt(''));
|
|
print(g.parseInt(' 123'));
|
|
print(g.parseInt('cafe', 16));
|
|
print(g.parseInt('01000001', 2)); // smallest supported radix
|
|
print(g.parseInt('z09gw', 36)); // largest supported radix
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
coercion
|
|
toString()
|
|
123
|
|
===*/
|
|
|
|
/* parseInt coercion: ToString() followed by string parsing. */
|
|
|
|
print('coercion');
|
|
|
|
try {
|
|
print(g.parseInt(
|
|
{ toString: function() { print('toString()'); return '123'; },
|
|
valueOf: function() { print('valueOf()'); return 123; } }
|
|
));
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
whitespace strip test
|
|
321
|
|
123
|
|
123
|
|
===*/
|
|
|
|
/* parseInt white space stripping.
|
|
*
|
|
* StrWhiteSpaceChar is WhiteSpace or LineTerminator; WHITESPACE_CODEPOINTS
|
|
* lists the codepoints.
|
|
*/
|
|
|
|
print('whitespace strip test');
|
|
|
|
function whiteSpaceStripTest() {
|
|
var t = [];
|
|
var i;
|
|
var txt;
|
|
|
|
// a simple test with only ASCII whitespace
|
|
txt = '\u0009\u000b\u000c\u0020\u00a0\u000a\u000d321.0';
|
|
print(g.parseInt(txt));
|
|
|
|
// txt will contain every whitespace codepoint followed by the number
|
|
for (i = 0; i < WHITESPACE_CODEPOINTS.length; i++) {
|
|
t.push(String.fromCharCode(WHITESPACE_CODEPOINTS[i]));
|
|
}
|
|
t.push('123.0');
|
|
txt = t.join('');
|
|
print(g.parseInt(txt));
|
|
|
|
// try with trailing garbage
|
|
print(g.parseInt(txt + 'xyz'));
|
|
}
|
|
|
|
try {
|
|
whiteSpaceStripTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
trailing garbage
|
|
123
|
|
123
|
|
123
|
|
123
|
|
123
|
|
123
|
|
-123
|
|
-123
|
|
-123
|
|
-128
|
|
128
|
|
-57005
|
|
4660
|
|
===*/
|
|
|
|
/* Trailing garbage is ignored. */
|
|
|
|
print('trailing garbage');
|
|
|
|
function trailingGarbageTest() {
|
|
// decimal
|
|
print(g.parseInt('123xxx'));
|
|
print(g.parseInt('123\uffff'));
|
|
print(g.parseInt('123\u0000'));
|
|
print(g.parseInt('+123xxx'));
|
|
print(g.parseInt('+123\uffff'));
|
|
print(g.parseInt(' +123\u0000'));
|
|
print(g.parseInt(' -123xxx'));
|
|
print(g.parseInt(' -123\uffff'));
|
|
print(g.parseInt(' -123\u0000'));
|
|
|
|
// a few tests in another radix
|
|
print(g.parseInt(' -10000000xxx', 2));
|
|
print(g.parseInt(' 10000000xxx', 2));
|
|
|
|
// whitespace is also "garbage"
|
|
print(g.parseInt(' -0xdead beefxxx', 16));
|
|
print(g.parseInt(' 1234 5678xxx', 16));
|
|
}
|
|
|
|
try {
|
|
trailingGarbageTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
fractions
|
|
12345678
|
|
12345678
|
|
12345678
|
|
-12345678
|
|
-12345678
|
|
-12345678
|
|
-128
|
|
128
|
|
===*/
|
|
|
|
/* Fractions (decimal or otherwise) as created by e.g. Number.prototype.toString()
|
|
* are ignored when using parseInt; they are treated as garbage.
|
|
*/
|
|
|
|
print('fractions');
|
|
|
|
function fractionsTest() {
|
|
// decimal
|
|
print(g.parseInt('12345678.9'));
|
|
print(g.parseInt('12345678.1'));
|
|
print(g.parseInt(' +12345678.9'));
|
|
print(g.parseInt(' -12345678.1'));
|
|
print(g.parseInt(' -12345678.9'));
|
|
print(g.parseInt(' -12345678.1'));
|
|
|
|
// a few tests in another radix
|
|
print(g.parseInt(' -10000000.001', 2));
|
|
print(g.parseInt(' 10000000.100', 2));
|
|
}
|
|
|
|
try {
|
|
fractionsTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
radix tests
|
|
NaN
|
|
8
|
|
1000
|
|
46656
|
|
NaN
|
|
1000
|
|
1000
|
|
1000
|
|
1000
|
|
1000
|
|
1000
|
|
46656
|
|
46656
|
|
NaN
|
|
8
|
|
1000
|
|
46656
|
|
NaN
|
|
NaN
|
|
8
|
|
1000
|
|
46656
|
|
NaN
|
|
42875
|
|
42875
|
|
46656
|
|
===*/
|
|
|
|
/* Valid radix range is 2 to 36, and is coerced with ToInt32. Note that
|
|
* because ToInt32() uses a modulo-based coercion, integer radix N is the
|
|
* same as radix N + k*2^32. Rounding is towards zero.
|
|
*
|
|
* R = 0 has special handling, it defaults R to 10 (step 9).
|
|
*/
|
|
|
|
print('radix tests');
|
|
|
|
function radixTest() {
|
|
var txt = "1000";
|
|
var tp32 = 256 * 256 * 256 * 256;
|
|
|
|
// basic integer range
|
|
print(g.parseInt(txt, 1));
|
|
print(g.parseInt(txt, 2));
|
|
print(g.parseInt(txt, 10));
|
|
print(g.parseInt(txt, 36)); // 1*36*36*36
|
|
print(g.parseInt(txt, 37));
|
|
|
|
// not given, undefined, 0 radix are the same and interpreted as radix 10
|
|
print(g.parseInt(txt));
|
|
print(g.parseInt(txt, undefined));
|
|
print(g.parseInt(txt, 0));
|
|
print(g.parseInt(txt, 10));
|
|
|
|
// round towards zero
|
|
print(g.parseInt(txt, 10.1));
|
|
print(g.parseInt(txt, 10.9));
|
|
print(g.parseInt(txt, 36.1));
|
|
print(g.parseInt(txt, 36.9));
|
|
|
|
// modulo effect
|
|
print(g.parseInt(txt, 1 + tp32));
|
|
print(g.parseInt(txt, 2 + tp32));
|
|
print(g.parseInt(txt, 10 + tp32));
|
|
print(g.parseInt(txt, 36 + tp32));
|
|
print(g.parseInt(txt, 37 + tp32));
|
|
print(g.parseInt(txt, 1 - tp32));
|
|
print(g.parseInt(txt, 2 - tp32));
|
|
print(g.parseInt(txt, 10 - tp32));
|
|
print(g.parseInt(txt, 36 - tp32));
|
|
print(g.parseInt(txt, 37 - tp32));
|
|
|
|
// fractional radixes work differently because of round-towards-zero.
|
|
// positive values round downwards before modulo computation; negative
|
|
// values effectively round upwards
|
|
print(g.parseInt(txt, 35.9 + tp32)); // 4294967331.9 -> 4294967331 -> 35 (after -2^32)
|
|
print(g.parseInt(txt, 35.9));
|
|
print(g.parseInt(txt, 35.9 - tp32)); // -4294967260.1 -> -4294967260 -> 36 (after +2^32)
|
|
}
|
|
|
|
try {
|
|
radixTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
radix 16
|
|
51966
|
|
-51966
|
|
51966
|
|
-51966
|
|
-51966
|
|
51966
|
|
-51966
|
|
51966
|
|
0
|
|
0
|
|
0
|
|
0
|
|
===*/
|
|
|
|
/* parseInt radix is defaulted to 16 if the string begins with "0x" or "0X".
|
|
* The prefix "0x" or "0X" is permitted (only) if radix is 16.
|
|
*/
|
|
|
|
print('radix 16');
|
|
|
|
function testRadix16(x, r, arg_count) {
|
|
var t;
|
|
|
|
try {
|
|
if (arg_count == 1) {
|
|
t = g.parseInt(x);
|
|
} else {
|
|
t = g.parseInt(x, r);
|
|
}
|
|
print(t);
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
}
|
|
|
|
function radix16Test() {
|
|
testRadix16('0xcafe', undefined, 1);
|
|
testRadix16('-0Xcafe', undefined, 1);
|
|
testRadix16(' 0xCAfe', undefined, 1); // whitespace + case variation
|
|
testRadix16(' -0XCAfe', undefined, 1);
|
|
|
|
testRadix16('-0xcafe', 16);
|
|
testRadix16('0Xcafe', 16);
|
|
testRadix16(' -0xCAfe', 16.5);
|
|
testRadix16(' 0XCAfe', 16.5);
|
|
|
|
/* The expected result here is not obvious. Let's consider the
|
|
* first case.
|
|
*
|
|
* In step 6, R will be 15, which causes us to execute step 8.b,
|
|
* i.e. stripPrefix will be false. Step 10 will then be skipped,
|
|
* and the '0x' prefix should NOT cause an automatic radix 16
|
|
* conversion.
|
|
*
|
|
* Parsing in base 15, the first character will be a valid digit
|
|
* (zero), while the second character will be garbage and terminate
|
|
* parsing. The result should, thus be 0.
|
|
*
|
|
* (However, at least V8/Rhino will parse these as hexadecimal.)
|
|
*/
|
|
|
|
testRadix16('0xcafe', 15);
|
|
testRadix16('0Xcafe', 15);
|
|
testRadix16('0x1234', 10);
|
|
testRadix16('0X1234', 10);
|
|
}
|
|
|
|
try {
|
|
radix16Test();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
radix 8
|
|
123
|
|
129
|
|
123
|
|
129
|
|
-123
|
|
-129
|
|
83
|
|
10
|
|
83
|
|
10
|
|
-83
|
|
-10
|
|
123
|
|
129
|
|
123
|
|
129
|
|
-123
|
|
-129
|
|
===*/
|
|
|
|
/* Radix 8 test.
|
|
*
|
|
* These is no standard automatic mechanism for using radix 8 (like
|
|
* "0x" or "0X" prefix for radix 16). However, both V8 and Rhino seem
|
|
* to use a leading zero to indicate automatic radix 8.
|
|
*
|
|
* This is not standard behavior, so test against this behavior
|
|
* (at least for now).
|
|
*/
|
|
|
|
/* FIXME: change Duktape behavior to match V8 and Rhino for octal? */
|
|
|
|
print('radix 8');
|
|
|
|
function radix8Test() {
|
|
// this should be interpreted as base-10; V8 and Rhino interpret these
|
|
// as octal (0129 will be parsed as "012" with 9 treated as garbage)
|
|
|
|
print(g.parseInt('0123'));
|
|
print(g.parseInt('0129'));
|
|
print(g.parseInt('+0123'));
|
|
print(g.parseInt('+0129'));
|
|
print(g.parseInt('-0123'));
|
|
print(g.parseInt('-0129'));
|
|
|
|
// explicit radix 8
|
|
print(g.parseInt('0123', 8));
|
|
print(g.parseInt('0129', 8));
|
|
print(g.parseInt('+0123', 8));
|
|
print(g.parseInt('+0129', 8));
|
|
print(g.parseInt('-0123', 8));
|
|
print(g.parseInt('-0129', 8));
|
|
|
|
// explicit radix 10
|
|
print(g.parseInt('0123', 10));
|
|
print(g.parseInt('0129', 10));
|
|
print(g.parseInt('+0123', 10));
|
|
print(g.parseInt('+0129', 10));
|
|
print(g.parseInt('-0123', 10));
|
|
print(g.parseInt('-0129', 10));
|
|
}
|
|
|
|
try {
|
|
radix8Test();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
signed values
|
|
123
|
|
-123
|
|
291
|
|
-291
|
|
66
|
|
-66
|
|
===*/
|
|
|
|
/* Signed values; test negative values in other radixes especially. */
|
|
|
|
print('signed values');
|
|
|
|
function signedValueTest() {
|
|
print(g.parseInt(' +123'));
|
|
print(g.parseInt(' -123'));
|
|
print(g.parseInt(' +0x123'));
|
|
print(g.parseInt(' -0X123'));
|
|
print(g.parseInt(' +123', 7));
|
|
print(g.parseInt(' -123', 7));
|
|
}
|
|
|
|
try {
|
|
signedValueTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
leading zeroes
|
|
123
|
|
123
|
|
-123
|
|
129
|
|
129
|
|
-129
|
|
57005
|
|
57005
|
|
-57005
|
|
668
|
|
668
|
|
-668
|
|
===*/
|
|
|
|
/* Leading zeroes.
|
|
*
|
|
* Note that V8 and Rhino use a leading zero (not followed by 'x' or 'X') to
|
|
* indicate an automatic radix 8 (octal). This doesn't seem spec compliant,
|
|
* so test against this for now.
|
|
*/
|
|
|
|
/* FIXME: change Duktape behavior to match V8 and Rhino for octal? */
|
|
|
|
print('leading zeroes');
|
|
|
|
function leadingZeroTest() {
|
|
// V8 will yield +/- 83 for this
|
|
print(g.parseInt('000123'));
|
|
print(g.parseInt('+000123'));
|
|
print(g.parseInt('-000123'));
|
|
|
|
// V8 will yield +/- 10 for this (012 = 10 octal, 9 is garbage)
|
|
print(g.parseInt('000129'));
|
|
print(g.parseInt('+000129'));
|
|
print(g.parseInt('-000129'));
|
|
|
|
print(g.parseInt('0x0000dead'));
|
|
print(g.parseInt('+0x0000dead'));
|
|
print(g.parseInt('-0x0000dead'));
|
|
|
|
print(g.parseInt('00001234', 8));
|
|
print(g.parseInt('+00001234', 8));
|
|
print(g.parseInt('-00001234', 8));
|
|
}
|
|
|
|
try {
|
|
leadingZeroTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
numbers below/above 2**53
|
|
(testdump)
|
|
9007199254740984
|
|
9007199254740985
|
|
9007199254740986
|
|
9007199254740987
|
|
9007199254740988
|
|
9007199254740989
|
|
9007199254740990
|
|
9007199254740991
|
|
9007199254740992
|
|
9007199254740992
|
|
9007199254740994
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740998
|
|
9007199254741000
|
|
9007199254741000
|
|
(parse decimals)
|
|
9007199254740992
|
|
9007199254740992
|
|
9007199254740994
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740998
|
|
9007199254741000
|
|
9007199254741000
|
|
(parse hex)
|
|
9007199254740992
|
|
9007199254740992
|
|
9007199254740994
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740998
|
|
9007199254741000
|
|
9007199254741000
|
|
(parse radix 2)
|
|
9007199254740992
|
|
9007199254740992
|
|
9007199254740994
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740998
|
|
9007199254741000
|
|
9007199254741000
|
|
(parse radix 4)
|
|
9007199254740992
|
|
9007199254740992
|
|
9007199254740994
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740998
|
|
9007199254741000
|
|
9007199254741000
|
|
(parse radix 8)
|
|
9007199254740992
|
|
9007199254740992
|
|
9007199254740994
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740998
|
|
9007199254741000
|
|
9007199254741000
|
|
(parse radix 32)
|
|
9007199254740992
|
|
9007199254740992
|
|
9007199254740994
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740998
|
|
9007199254741000
|
|
9007199254741000
|
|
(parse radix 36)
|
|
9007199254740992
|
|
9007199254740992
|
|
9007199254740994
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740996
|
|
9007199254740998
|
|
9007199254741000
|
|
9007199254741000
|
|
===*/
|
|
|
|
/* Numbers close to just below and above the IEEE double range (53 bits). */
|
|
|
|
print('numbers below/above 2**53');
|
|
|
|
function numbersNear53BitsTest() {
|
|
var two_to_53 = 65536*65536*65536*2*2*2*2*2; // 2**53
|
|
var i;
|
|
|
|
// demonstrate how behavior after 2**53 changes
|
|
// FIXME: elaborate on the rounding behavior
|
|
print('(testdump)');
|
|
for (i = -8; i <= 8; i++) {
|
|
print(two_to_53 + i);
|
|
}
|
|
|
|
print('(parse decimals)');
|
|
print(g.parseInt('9007199254740992'));
|
|
print(g.parseInt('9007199254740993'));
|
|
print(g.parseInt('9007199254740994'));
|
|
print(g.parseInt('9007199254740995'));
|
|
print(g.parseInt('9007199254740996'));
|
|
print(g.parseInt('9007199254740997'));
|
|
print(g.parseInt('9007199254740998'));
|
|
print(g.parseInt('9007199254740999'));
|
|
print(g.parseInt('9007199254741000'));
|
|
|
|
print('(parse hex)');
|
|
print(g.parseInt('0x20000000000000'));
|
|
print(g.parseInt('0x20000000000001'));
|
|
print(g.parseInt('0x20000000000002'));
|
|
print(g.parseInt('0x20000000000003'));
|
|
print(g.parseInt('0x20000000000004'));
|
|
print(g.parseInt('0x20000000000005'));
|
|
print(g.parseInt('0x20000000000006'));
|
|
print(g.parseInt('0x20000000000007'));
|
|
print(g.parseInt('0x20000000000008'));
|
|
|
|
print('(parse radix 2)');
|
|
print(g.parseInt('100000000000000000000000000000000000000000000000000000', 2));
|
|
print(g.parseInt('100000000000000000000000000000000000000000000000000001', 2));
|
|
print(g.parseInt('100000000000000000000000000000000000000000000000000010', 2));
|
|
print(g.parseInt('100000000000000000000000000000000000000000000000000011', 2));
|
|
print(g.parseInt('100000000000000000000000000000000000000000000000000100', 2));
|
|
print(g.parseInt('100000000000000000000000000000000000000000000000000101', 2));
|
|
print(g.parseInt('100000000000000000000000000000000000000000000000000110', 2));
|
|
print(g.parseInt('100000000000000000000000000000000000000000000000000111', 2));
|
|
print(g.parseInt('100000000000000000000000000000000000000000000000001000', 2));
|
|
|
|
print('(parse radix 4)');
|
|
print(g.parseInt('200000000000000000000000000', 4));
|
|
print(g.parseInt('200000000000000000000000001', 4));
|
|
print(g.parseInt('200000000000000000000000002', 4));
|
|
print(g.parseInt('200000000000000000000000003', 4));
|
|
print(g.parseInt('200000000000000000000000010', 4));
|
|
print(g.parseInt('200000000000000000000000011', 4));
|
|
print(g.parseInt('200000000000000000000000012', 4));
|
|
print(g.parseInt('200000000000000000000000013', 4));
|
|
print(g.parseInt('200000000000000000000000020', 4));
|
|
|
|
print('(parse radix 8)');
|
|
print(g.parseInt('400000000000000000', 8));
|
|
print(g.parseInt('400000000000000001', 8));
|
|
print(g.parseInt('400000000000000002', 8));
|
|
print(g.parseInt('400000000000000003', 8));
|
|
print(g.parseInt('400000000000000004', 8));
|
|
print(g.parseInt('400000000000000005', 8));
|
|
print(g.parseInt('400000000000000006', 8));
|
|
print(g.parseInt('400000000000000007', 8));
|
|
print(g.parseInt('400000000000000010', 8));
|
|
|
|
print('(parse radix 32)');
|
|
print(g.parseInt('80000000000', 32));
|
|
print(g.parseInt('80000000001', 32));
|
|
print(g.parseInt('80000000002', 32));
|
|
print(g.parseInt('80000000003', 32));
|
|
print(g.parseInt('80000000004', 32));
|
|
print(g.parseInt('80000000005', 32));
|
|
print(g.parseInt('80000000006', 32));
|
|
print(g.parseInt('80000000007', 32));
|
|
print(g.parseInt('80000000008', 32));
|
|
|
|
print('(parse radix 36)');
|
|
print(g.parseInt('2gosa7pa2gw', 36));
|
|
print(g.parseInt('2gosa7pa2gx', 36));
|
|
print(g.parseInt('2gosa7pa2gy', 36));
|
|
print(g.parseInt('2gosa7pa2gz', 36));
|
|
print(g.parseInt('2gosa7pa2h0', 36));
|
|
print(g.parseInt('2gosa7pa2h1', 36));
|
|
print(g.parseInt('2gosa7pa2h2', 36));
|
|
print(g.parseInt('2gosa7pa2h3', 36));
|
|
print(g.parseInt('2gosa7pa2h4', 36));
|
|
|
|
/* Parsing results for radix 3 are not required to be exact, so
|
|
* printing these results would result in a custom test. V8 and
|
|
* Rhino also have different results for the commented out radix 3
|
|
* test below in practice, too.
|
|
*/
|
|
|
|
/*
|
|
print('(parse radix 3)');
|
|
print(g.parseInt('1121202011211211122211100012101112', 3));
|
|
print(g.parseInt('1121202011211211122211100012101120', 3));
|
|
print(g.parseInt('1121202011211211122211100012101121', 3));
|
|
print(g.parseInt('1121202011211211122211100012101122', 3));
|
|
print(g.parseInt('1121202011211211122211100012101200', 3));
|
|
print(g.parseInt('1121202011211211122211100012101201', 3));
|
|
print(g.parseInt('1121202011211211122211100012101202', 3));
|
|
print(g.parseInt('1121202011211211122211100012101210', 3));
|
|
print(g.parseInt('1121202011211211122211100012101211', 3));
|
|
*/
|
|
}
|
|
|
|
try {
|
|
numbersNear53BitsTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
large number test
|
|
2 3.402823669209385e+38 true
|
|
3 diff ok true
|
|
4 3.402823669209385e+38 true
|
|
5 diff ok true
|
|
6 diff ok true
|
|
7 diff ok true
|
|
8 3.402823669209385e+38 true
|
|
9 diff ok true
|
|
10 3.402823669209385e+38 true
|
|
11 diff ok true
|
|
12 diff ok true
|
|
13 diff ok true
|
|
14 diff ok true
|
|
15 diff ok true
|
|
16 3.402823669209385e+38 true
|
|
17 diff ok true
|
|
18 diff ok true
|
|
19 diff ok true
|
|
20 diff ok true
|
|
21 diff ok true
|
|
22 diff ok true
|
|
23 diff ok true
|
|
24 diff ok true
|
|
25 diff ok true
|
|
26 diff ok true
|
|
27 diff ok true
|
|
28 diff ok true
|
|
29 diff ok true
|
|
30 diff ok true
|
|
31 diff ok true
|
|
32 3.402823669209385e+38 true
|
|
33 diff ok true
|
|
34 diff ok true
|
|
35 diff ok true
|
|
36 diff ok true
|
|
===*/
|
|
|
|
/* Numbers much higher than 53 bits.
|
|
*
|
|
* Check 2**128 in all supported radixes.
|
|
*/
|
|
|
|
/*
|
|
digits = '0123456789abcdefghijklmnopqrstuvwxyz';
|
|
print('// len(digits) = %d' % len(digits))
|
|
|
|
def tobase(x,n):
|
|
t = []
|
|
while x != 0:
|
|
t.append(digits[x % n])
|
|
x = x / n
|
|
t.reverse()
|
|
return ''.join(t)
|
|
|
|
print('[')
|
|
for i in xrange(2, 37):
|
|
print('{ base: %d, str: "%s" },' % (i, tobase(2**128, i)))
|
|
|
|
print(']')
|
|
*/
|
|
|
|
print('large number test');
|
|
|
|
function largeNumberTest() {
|
|
var inputs = [
|
|
{ base: 2, str: "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" },
|
|
{ base: 3, str: "202201102121002021012000211012011021221022212021111001022110211020010021100121011" },
|
|
{ base: 4, str: "10000000000000000000000000000000000000000000000000000000000000000" },
|
|
{ base: 5, str: "11031110441201303134210404233413032443021130230130231311" },
|
|
{ base: 6, str: "23053353530155550541354043543542243325553444410304" },
|
|
{ base: 7, str: "3115512162124626343001006330151620356026315304" },
|
|
{ base: 8, str: "4000000000000000000000000000000000000000000" },
|
|
{ base: 9, str: "22642532235024164257285244038424203240534" },
|
|
{ base: 10, str: "340282366920938463463374607431768211456" },
|
|
{ base: 11, str: "1000a504186892265432152aa27a7929366353" },
|
|
{ base: 12, str: "5916b64b41143526a777873841863a6a6994" },
|
|
{ base: 13, str: "47168c9c477c94ba75a2bc735955c7aa139" },
|
|
{ base: 14, str: "51a45cb9506962a31983dac25409715d04" },
|
|
{ base: 15, str: "7d491176809c28848a561186d4857d321" },
|
|
{ base: 16, str: "100000000000000000000000000000000" },
|
|
{ base: 17, str: "279078gb8485d7b72e2ag3c08ed3g121" },
|
|
{ base: 18, str: "78a399ccdeb5bd6ha3184c0fh64da64" },
|
|
{ base: 19, str: "1910510fd19aig25hc6g5gebeb98h84" },
|
|
{ base: 20, str: "66f609c19456i2h147iga2g17b68cg" },
|
|
{ base: 21, str: "1b71cc7c703ijd4g3k82ff6keb3c04" },
|
|
{ base: 22, str: "8h8b5gheh7legf73fb0had7bhd3de" },
|
|
{ base: 23, str: "2c59d9lld38jeh6fgh5m42j82lfdd" },
|
|
{ base: 24, str: "iamei9lfd1i5k10n7fnfn25b3kag" },
|
|
{ base: 25, str: "6365o71fgjb44dj83en26fd1fd86" },
|
|
{ base: 26, str: "23745echihn4jcil7jec2kd69a1m" },
|
|
{ base: 27, str: "kjbg2750m547p8n7d18cm6379g4" },
|
|
{ base: 28, str: "81a71cgjeb6cjo7odb65d7icrl4" },
|
|
{ base: 29, str: "36l6q70ega3gd8s9ag8rce14rap" },
|
|
{ base: 30, str: "1a4p5qh8koob2e2gknbn3jbm88g" },
|
|
{ base: 31, str: "hleoq9ui363gg16lmp8srn1je8" },
|
|
{ base: 32, str: "80000000000000000000000000" },
|
|
{ base: 33, str: "3nakotlgi17b10fs1825j5cf1p" },
|
|
{ base: 34, str: "1ppi6nphe0ckbctn7qwp6qrh9i" },
|
|
{ base: 35, str: "try5wbbiprfp7r727m0oyq2wb" },
|
|
{ base: 36, str: "f5lxx1zz5pnorynqglhzmsp34" },
|
|
];
|
|
var results = [];
|
|
var i;
|
|
var diff;
|
|
|
|
// these are required to be exact by the specification: since 2**128 can be represented
|
|
// exactly, the result must be exact and equal for all of these
|
|
var required_exact = { '2': true, '4': true, '8': true, '16': true, '32': true, '10': true };
|
|
|
|
for (i = 0; i < inputs.length; i++) {
|
|
results.push(g.parseInt(inputs[i].str, inputs[i].base));
|
|
|
|
if (required_exact[inputs[i].base]) {
|
|
// Assume base 2 is correct and compare everything against that
|
|
// for those radixes for which results are required to be bit
|
|
// exact.
|
|
|
|
print(inputs[i].base, results[i], results[i] === results[0]);
|
|
} else {
|
|
// Fon't print out the results for other bases, as they don't
|
|
// necessarily match (even in practice).
|
|
//
|
|
// For 2**128, given mantissa is 53 bits (one bit implicit),
|
|
// expect around some multiple of 2**(128-53) = 2**75 =
|
|
// 3.777893186295716e+22 of error. Limit allows over 10-fold
|
|
// error now.
|
|
|
|
diff = results[i] - results[0];
|
|
print(inputs[i].base, 'diff ok', Math.abs(diff) < 4e23);
|
|
|
|
//print(inputs[i].base, results[i], results[i] === results[0]);
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
largeNumberTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
/*===
|
|
digit cases
|
|
3735928559
|
|
1047601316294262
|
|
===*/
|
|
|
|
/* Upper and lowercase digits. */
|
|
|
|
print('digit cases');
|
|
|
|
function digitCaseTest() {
|
|
print(g.parseInt('0xdeADbEeF'));
|
|
print(g.parseInt('aBcDeFgGhI', 36));
|
|
}
|
|
|
|
try {
|
|
digitCaseTest();
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
|
|
|