rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js
1 // empty line needed here
3 (function(numberPrototype) {
8 return (((x * (y >> 16)) << 16) + x * (y & 0xFFFF)) | 0;
10 var __m32 = 0xFFFFFFFF;
12 numberPrototype.next32 = function(low) {
16 var l = new Number(low);
21 numberPrototype.high32 = function() {
25 return x.lo ? x.lo : x;
28 return x.hi ? x.hi : (Math.floor(low32(x) / (__m32 + 1))) | 0;
30 numberPrototype.toFP = function() {
31 return this.hi ? this.hi * (__m32 + 1) + low32(this) : low32(this);
33 numberPrototype.toLong = function() {
34 var hi = (low32(this) / (__m32 + 1)) | 0;
35 var low = (low32(this) % (__m32 + 1)) | 0;
40 if (low32(this) < 0) {
44 return hi.next32(low);
47 numberPrototype.toExactString = function() {
49 // check for Long.MIN_VALUE
50 if ((this.hi == (0x80000000 | 0)) && (low32(this) == 0)) {
51 return '-9223372036854775808';
54 var a = [6, 9, 2, 7, 6, 9, 4, 9, 2, 4];
57 var neg = this.hi < 0;
64 var low = low32(this);
66 for (var i = 0; i < a.length; i++) {
68 var low_digit = low % 10;
69 digit = (res % 10) + low_digit;
71 low = Math.floor(low / 10);
72 res = Math.floor(res / 10);
78 s = String(digit).concat(s);
80 s = String(res).concat(s).replace(/^0+/, '');
81 return (neg ? '-' : '').concat(s);
83 return String(low32(this));
86 function add64(x, y) {
87 var low = low32(x) + low32(y);
93 var hi = (high32(x) + high32(y) + carry) | 0;
94 return hi.next32(low);
97 function sub64(x, y) {
98 var low = low32(x) - low32(y);
104 var hi = (high32(x) - high32(y) - carry) | 0;
105 return hi.next32(low);
108 function mul64(x, y) {
109 var low = mul32(low32(x), low32(y));
110 low += (low < 0) ? (__m32 + 1) : 0;
111 // first count upper 32 bits of (x.low * x.low)
115 for (var i = 0; i < 32; i++) {
121 hi_low += (hi_hi & 1) ? 0x8000 : 0;
125 var hi = (hi_hi << 16) + hi_low;
127 var m1 = mul32(high32(x), low32(y));
128 var m2 = mul32(low32(x), high32(y));
129 hi = add32(add32(hi, m1), m2);
131 return hi.next32(low);
134 function and64(x, y) {
135 var low = low32(x) & low32(y);
136 low += (low < 0) ? (__m32 + 1) : 0;
138 var hi = x.hi & y.hi;
139 return hi.next32(low);
145 function or64(x, y) {
146 var low = low32(x) | low32(y);
147 low += (low < 0) ? (__m32 + 1) : 0;
149 var hi = x.hi | y.hi;
150 return hi.next32(low);
155 function xor64(x, y) {
156 var low = low32(x) ^ low32(y);
157 low += (low < 0) ? (__m32 + 1) : 0;
159 var hi = x.hi ^ y.hi;
160 return hi.next32(low);
166 function shl64(thiz, x) {
168 if (x === 0) return thiz;
170 var hi = low32(thiz) << (x - 32);
173 var hi = high32(thiz) << x;
174 var low_reminder = low32(thiz) >> (32 - x);
176 var low = low32(thiz) << x;
177 low += (low < 0) ? (__m32 + 1) : 0;
178 return hi.next32(low);
182 function shr64(thiz, x) {
184 if (x === 0) return thiz;
186 var low = high32(thiz) >> (x - 32);
187 low += (low < 0) ? (__m32 + 1) : 0;
190 var low = low32(thiz) >>> x;
191 var hi_reminder = high32(thiz) << (32 - x);
193 low += (low < 0) ? (__m32 + 1) : 0;
194 var hi = high32(thiz) >> x;
195 return hi.next32(low);
199 function ushr64(thiz, x) {
201 if (x === 0) return thiz;
203 var low = high32(thiz) >>> (x - 32);
204 low += (low < 0) ? (__m32 + 1) : 0;
207 var low = low32(thiz) >>> x;
208 var hi_reminder = high32(thiz) << (32 - x);
210 low += (low < 0) ? (__m32 + 1) : 0;
211 var hi = high32(thiz) >>> x;
212 return hi.next32(low);
216 function compare64(x, y) {
217 if (high32(x) === high32(y)) {
220 return (lox < loy) ? -1 : ((lox > loy) ? 1 : 0);
222 return (high32(x) < high32(y)) ? -1 : 1;
228 if ((hi === 0) && (low < 0)) {
233 low += (low < 0) ? (__m32 + 1) : 0;
234 var ret = hi.next32(low);
235 return add64(ret, 1);
238 function __handleDivByZero() {
239 var exception = new vm.java_lang_ArithmeticException;
240 vm.java_lang_ArithmeticException(false).constructor
241 .cons__VLjava_lang_String_2.call(exception, "/ by zero");
246 function __Int64(hi32, lo32) {
247 this.hi32 = hi32 | 0;
248 this.lo32 = lo32 | 0;
250 this.get32 = function(bitIndex) {
254 var selector = bitIndex >>> 5;
272 var shift = bitIndex & 31;
277 return (v1 << (32 - shift)) | (v0 >>> shift);
280 this.get16 = function(bitIndex) {
281 return this.get32(bitIndex) & 0xffff;
284 this.set16 = function(bitIndex, value) {
286 var shift = bitIndex & 15;
287 var svalue = (value & 0xffff) << shift;
288 var smask = 0xffff << shift;
289 var selector = bitIndex >>> 4;
294 this.lo32 = (this.lo32 & ~(smask >>> 16))
298 this.lo32 = (this.lo32 & ~smask) | svalue;
301 this.lo32 = (this.lo32 & ~(smask << 16))
303 this.hi32 = (this.hi32 & ~(smask >>> 16))
307 this.hi32 = (this.hi32 & ~smask) | svalue;
310 this.hi32 = (this.hi32 & ~(smask << 16))
316 this.getDigit = function(index, shift) {
317 return this.get16((index << 4) - shift);
320 this.getTwoDigits = function(index, shift) {
321 return this.get32(((index - 1) << 4) - shift);
324 this.setDigit = function(index, shift, value) {
325 this.set16((index << 4) - shift, value);
328 this.countSignificantDigits = function() {
332 if (this.hi32 === 0) {
333 if (this.lo32 === 0) {
338 remaining = this.lo32;
341 remaining = this.hi32;
348 return (remaining < 65536) ? sd - 1 : sd;
351 this.toNumber = function() {
352 var lo32 = this.lo32;
357 return this.hi32.next32(lo32);
361 function __countLeadingZeroes16(number) {
374 if (number < 16384) {
379 return (number < 32768) ? nlz + 1 : nlz;
382 // q = u / v; r = u - q * v;
384 function __div64(q, r, u, v) {
385 var m = u.countSignificantDigits();
386 var n = v.countSignificantDigits();
391 // v has single digit
392 var vd = v.getDigit(0, 0);
394 for (var i = m - 1; i >= 0; --i) {
395 var ui = (carry << 16) | u.getDigit(i, 0);
399 var qi = (ui / vd) | 0;
400 q.setDigit(i, 0, qi);
401 carry = ui - qi * vd;
417 var nrm = __countLeadingZeroes16(v.getDigit(n - 1, 0));
419 var vd1 = v.getDigit(n - 1, nrm);
420 var vd0 = v.getDigit(n - 2, nrm);
421 for (var j = m - n; j >= 0; --j) {
422 // Calculate qj estimate
423 var ud21 = r.getTwoDigits(j + n, nrm);
424 var ud2 = ud21 >>> 16;
429 var qest = (ud2 === vd1) ? 0xFFFF : ((ud21 / vd1) | 0);
430 var rest = ud21 - qest * vd1;
432 // 0 <= (qest - qj) <= 2
434 // Refine qj estimate
435 var ud0 = r.getDigit(j + n - 2, nrm);
436 while ((qest * vd0) > ((rest * 0x10000) + ud0)) {
441 // 0 <= (qest - qj) <= 1
443 // Multiply and subtract
445 for (var i = 0; i < n; ++i) {
446 var vi = qest * v.getDigit(i, nrm);
447 var ui = r.getDigit(i + j, nrm) - carry - (vi & 0xffff);
448 r.setDigit(i + j, nrm, ui);
449 carry = (vi >>> 16) - (ui >> 16);
451 var uj = ud2 - carry;
459 for (var i = 0; i < n; ++i) {
460 var ui = r.getDigit(i + j, nrm) + v.getDigit(i, nrm)
462 r.setDigit(i + j, nrm, ui);
468 q.setDigit(j, 0, qest);
469 r.setDigit(j + n, nrm, uj);
473 function div64(x, y) {
474 var negateResult = false;
477 if ((high32(x) & 0x80000000) !== 0) {
479 negateResult = !negateResult;
484 if ((high32(y) & 0x80000000) !== 0) {
486 negateResult = !negateResult;
491 if ((low32(v) === 0) && (high32(v) === 0)) {
495 if (high32(u) === 0) {
496 if (high32(v) === 0) {
497 var result = (low32(u) / low32(v)) | 0;
498 return negateResult ? neg64(result) : result;
504 var u64 = new __Int64(high32(u), low32(u));
505 var v64 = new __Int64(high32(v), low32(v));
506 var q64 = new __Int64(0, 0);
507 var r64 = new __Int64(0, 0);
509 __div64(q64, r64, u64, v64);
511 var result = q64.toNumber();
512 return negateResult ? neg64(result) : result;
515 function mod64(x, y) {
516 var negateResult = false;
519 if ((high32(x) & 0x80000000) !== 0) {
521 negateResult = !negateResult;
526 if ((high32(y) & 0x80000000) !== 0) {
532 if ((low32(v) === 0) && (high32(v) === 0)) {
536 if (high32(u) === 0) {
537 var result = (high32(v) === 0) ? (low32(u) % low32(v)) : low32(u);
538 return negateResult ? neg64(result) : result;
541 var u64 = new __Int64(high32(u), low32(u));
542 var v64 = new __Int64(high32(v), low32(v));
543 var q64 = new __Int64(0, 0);
544 var r64 = new __Int64(0, 0);
546 __div64(q64, r64, u64, v64);
548 var result = r64.toNumber();
549 return negateResult ? neg64(result) : result;
552 var b = numberPrototype['__bit64'] = {};
565 b.compare64 = compare64;
566 })(Number.prototype);
568 vm.java_lang_Number(false);