emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js
brancharithmetic
changeset 774 42bc1e89134d
parent 755 5652acd48509
parent 773 406faa8bc64f
child 778 6f8683517f1f
     1.1 --- a/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js	Mon Feb 25 19:00:08 2013 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,544 +0,0 @@
     1.4 -// empty line needed here
     1.5 -Number.prototype.add32 = function(x) { return (this + x) | 0; };
     1.6 -Number.prototype.sub32 = function(x) { return (this - x) | 0; };
     1.7 -Number.prototype.mul32 = function(x) { 
     1.8 -    return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
     1.9 -};
    1.10 -Number.prototype.neg32 = function() { return (-this) | 0; };
    1.11 -
    1.12 -Number.prototype.toInt8 = function()  { return (this << 24) >> 24; };
    1.13 -Number.prototype.toInt16 = function() { return (this << 16) >> 16; };
    1.14 -
    1.15 -var __m32 = 0xFFFFFFFF;
    1.16 -
    1.17 -Number.prototype.next32 = function(low) {
    1.18 -  if (this === 0) {
    1.19 -    return low;
    1.20 -  }
    1.21 -  var l = new Number(low);
    1.22 -  l.hi = this | 0;
    1.23 -  return l;
    1.24 -};
    1.25 -
    1.26 -Number.prototype.high32 = function() { 
    1.27 -    return this.hi ? this.hi : (Math.floor(this / (__m32+1))) | 0;
    1.28 -};
    1.29 -Number.prototype.toInt32 = function() { return this | 0; };
    1.30 -Number.prototype.toFP = function() {
    1.31 -    return this.hi ? this.hi * (__m32+1) + this : this;
    1.32 -};
    1.33 -Number.prototype.toLong = function() {
    1.34 -    var hi = (this > __m32) ? (Math.floor(this / (__m32+1))) | 0 : 0;
    1.35 -    return hi.next32(Math.floor(this % (__m32+1)));
    1.36 -};
    1.37 -
    1.38 -Number.prototype.toExactString = function() {
    1.39 -    if (this.hi) {
    1.40 -        // check for Long.MIN_VALUE
    1.41 -        if ((this.hi == (0x80000000 | 0)) && (this == 0)) {
    1.42 -            return '-9223372036854775808';
    1.43 -        }
    1.44 -        var res = 0;
    1.45 -        var a = [ 6,9,2,7,6,9,4,9,2,4 ];
    1.46 -        var s = '';
    1.47 -        var digit;
    1.48 -        var neg = this.hi < 0;
    1.49 -        if (neg) {
    1.50 -            var x = this.neg64();
    1.51 -            var hi = x.hi;
    1.52 -            var low = x;
    1.53 -        } else {
    1.54 -            var hi = this.hi;
    1.55 -            var low = this;
    1.56 -        }
    1.57 -        for (var i = 0; i < a.length; i++) {
    1.58 -            res += hi * a[i];
    1.59 -            var low_digit = low % 10;
    1.60 -            digit = (res % 10) + low_digit;
    1.61 -
    1.62 -            low = Math.floor(low / 10);
    1.63 -            res = Math.floor(res / 10);
    1.64 -
    1.65 -            if (digit >= 10) {
    1.66 -                digit -= 10;
    1.67 -                res++;
    1.68 -            }
    1.69 -            s = String(digit).concat(s);
    1.70 -        }
    1.71 -        s = String(res).concat(s).replace(/^0+/, '');
    1.72 -        return (neg ? '-' : '').concat(s);
    1.73 -    }
    1.74 -    return String(this);
    1.75 -};
    1.76 -
    1.77 -Number.prototype.add64 = function(x) {
    1.78 -    var low = this + x;
    1.79 -    carry = 0;
    1.80 -    if (low > __m32) {
    1.81 -        carry = 1;
    1.82 -        low -= (__m32+1);
    1.83 -    }
    1.84 -    var hi = (this.high32() + x.high32() + carry) | 0;
    1.85 -    return hi.next32(low);
    1.86 -};
    1.87 -
    1.88 -Number.prototype.sub64 = function(x) {
    1.89 -    var low = this - x;
    1.90 -    carry = 0;
    1.91 -    if (low < 0) {
    1.92 -        carry = 1;
    1.93 -        low += (__m32+1);
    1.94 -    }
    1.95 -    var hi = (this.high32() - x.high32() - carry) | 0;
    1.96 -    return hi.next32(low);
    1.97 -};
    1.98 -
    1.99 -Number.prototype.mul64 = function(x) {
   1.100 -    var low = this.mul32(x);
   1.101 -    low += (low < 0) ? (__m32+1) : 0;
   1.102 -    // first count upper 32 bits of (this.low * x.low)
   1.103 -    var hi_hi = 0;
   1.104 -    var hi_low = 0;
   1.105 -    var m = 1;
   1.106 -    for (var i = 0; i < 32; i++) {
   1.107 -        if (x & m) {
   1.108 -            hi_hi += this >>> 16;
   1.109 -            hi_low += this & 0xFFFF
   1.110 -        }
   1.111 -        hi_low >>= 1;
   1.112 -        hi_low += (hi_hi & 1) ? 0x8000 : 0;
   1.113 -        hi_hi >>= 1;
   1.114 -        m <<= 1;
   1.115 -    }
   1.116 -    var hi = (hi_hi << 16) + hi_low;
   1.117 -    
   1.118 -    var m1 = this.high32().mul32(x);
   1.119 -    var m2 = this.mul32(x.high32());
   1.120 -    hi = hi.add32(m1).add32(m2);
   1.121 -    
   1.122 -    return hi.next32(low);
   1.123 -};
   1.124 -
   1.125 -Number.prototype.and64 = function(x) {
   1.126 -    var low = this & x;
   1.127 -    low += (low < 0) ? (__m32+1) : 0;
   1.128 -    if (this.hi && x.hi) {
   1.129 -        var hi = this.hi & x.hi;
   1.130 -        return hi.next32(low);
   1.131 -    };
   1.132 -    return low;
   1.133 -};
   1.134 -
   1.135 -Number.prototype.or64 = function(x) {
   1.136 -    var low = this | x;
   1.137 -    low += (low < 0) ? (__m32+1) : 0;
   1.138 -    if (this.hi || x.hi) {
   1.139 -        var hi = this.hi | x.hi;
   1.140 -        return hi.next32(low);
   1.141 -    };
   1.142 -    return low;
   1.143 -};
   1.144 -
   1.145 -Number.prototype.xor64 = function(x) {
   1.146 -    var low = this ^ x;
   1.147 -    low += (low < 0) ? (__m32+1) : 0;
   1.148 -    if (this.hi || x.hi) {
   1.149 -        var hi = this.hi ^ x.hi;
   1.150 -        return hi.next32(low);
   1.151 -    };
   1.152 -    return low;
   1.153 -};
   1.154 -
   1.155 -Number.prototype.shl64 = function(x) {
   1.156 -    if (x >= 32) {
   1.157 -        var hi = this << (x - 32);
   1.158 -        return hi.next32(0);
   1.159 -    } else {
   1.160 -        var hi = this.high32() << x;
   1.161 -        var low_reminder = this >> (32 - x);
   1.162 -        hi |= low_reminder;
   1.163 -        var low = this << x;
   1.164 -        low += (low < 0) ? (__m32+1) : 0;
   1.165 -        return hi.next32(low);
   1.166 -    }
   1.167 -};
   1.168 -
   1.169 -Number.prototype.shr64 = function(x) {
   1.170 -    if (x >= 32) {
   1.171 -        var low = this.high32() >> (x - 32);
   1.172 -        low += (low < 0) ? (__m32+1) : 0;
   1.173 -        return low;
   1.174 -    } else {
   1.175 -        var low = this >> x;
   1.176 -        var hi_reminder = this.high32() << (32 - x);
   1.177 -        low |= hi_reminder;
   1.178 -        low += (low < 0) ? (__m32+1) : 0;
   1.179 -        var hi = this.high32() >> x;
   1.180 -        return hi.next32(low);
   1.181 -    }
   1.182 -};
   1.183 -
   1.184 -Number.prototype.ushr64 = function(x) {
   1.185 -    if (x >= 32) {
   1.186 -        var low = this.high32() >>> (x - 32);
   1.187 -        low += (low < 0) ? (__m32+1) : 0;
   1.188 -        return low;
   1.189 -    } else {
   1.190 -        var low = this >>> x;
   1.191 -        var hi_reminder = this.high32() << (32 - x);
   1.192 -        low |= hi_reminder;
   1.193 -        low += (low < 0) ? (__m32+1) : 0;
   1.194 -        var hi = this.high32() >>> x;
   1.195 -        return hi.next32(low);
   1.196 -    }
   1.197 -};
   1.198 -
   1.199 -Number.prototype.compare64 = function(x) {
   1.200 -    if (this.high32() === x.high32()) {
   1.201 -        return (this < x) ? -1 : ((this > x) ? 1 : 0);
   1.202 -    }
   1.203 -    return (this.high32() < x.high32()) ? -1 : 1;
   1.204 -};
   1.205 -
   1.206 -Number.prototype.neg64 = function() {
   1.207 -    var hi = this.high32();
   1.208 -    var low = this;
   1.209 -    if ((hi === 0) && (low < 0)) { return -low; }
   1.210 -    hi = ~hi;
   1.211 -    low = ~low;
   1.212 -    low += (low < 0) ? (__m32+1) : 0;
   1.213 -    var ret = hi.next32(low);
   1.214 -    return ret.add64(1);
   1.215 -};
   1.216 -
   1.217 -(function(numberPrototype) {
   1.218 -    function __handleDivByZero() {
   1.219 -        var exception = new vm.java_lang_ArithmeticException;
   1.220 -        vm.java_lang_ArithmeticException(false).constructor
   1.221 -          .cons__VLjava_lang_String_2.call(exception, "/ by zero");
   1.222 -
   1.223 -        throw exception;
   1.224 -    }
   1.225 -
   1.226 -    function __Int64(hi32, lo32) {
   1.227 -        this.hi32 = hi32 | 0;
   1.228 -        this.lo32 = lo32 | 0;
   1.229 -
   1.230 -        this.get32 = function(bitIndex) {
   1.231 -            var v0;
   1.232 -            var v1;
   1.233 -            bitIndex += 32;
   1.234 -            var selector = bitIndex >>> 5;
   1.235 -            switch (selector) {
   1.236 -                case 0:
   1.237 -                    v0 = 0;
   1.238 -                    v1 = this.lo32;
   1.239 -                    break;
   1.240 -                case 1:
   1.241 -                    v0 = this.lo32;
   1.242 -                    v1 = this.hi32;
   1.243 -                    break;
   1.244 -                case 2:
   1.245 -                    v0 = this.hi32;
   1.246 -                    v1 = 0;
   1.247 -                    break
   1.248 -                default:
   1.249 -                    return 0;
   1.250 -            }
   1.251 -
   1.252 -            var shift = bitIndex & 31;
   1.253 -            if (shift === 0) {
   1.254 -                return v0;
   1.255 -            }
   1.256 -
   1.257 -            return (v1 << (32 - shift)) | (v0 >>> shift);
   1.258 -        }
   1.259 -
   1.260 -        this.get16 = function(bitIndex) {
   1.261 -            return this.get32(bitIndex) & 0xffff;
   1.262 -        }
   1.263 -
   1.264 -        this.set16 = function(bitIndex, value) {
   1.265 -            bitIndex += 32;
   1.266 -            var shift = bitIndex & 15;
   1.267 -            var svalue = (value & 0xffff) << shift; 
   1.268 -            var smask = 0xffff << shift;
   1.269 -            var selector = bitIndex >>> 4;
   1.270 -            switch (selector) {
   1.271 -                case 0:
   1.272 -                    break;
   1.273 -                case 1:
   1.274 -                    this.lo32 = (this.lo32 & ~(smask >>> 16))
   1.275 -                                    | (svalue >>> 16);
   1.276 -                    break;
   1.277 -                case 2:
   1.278 -                    this.lo32 = (this.lo32 & ~smask) | svalue;
   1.279 -                    break;
   1.280 -                case 3:
   1.281 -                    this.lo32 = (this.lo32 & ~(smask << 16))
   1.282 -                                    | (svalue << 16);
   1.283 -                    this.hi32 = (this.hi32 & ~(smask >>> 16))
   1.284 -                                    | (svalue >>> 16);
   1.285 -                    break;
   1.286 -                case 4:
   1.287 -                    this.hi32 = (this.hi32 & ~smask) | svalue;
   1.288 -                    break;
   1.289 -                case 5:
   1.290 -                    this.hi32 = (this.hi32 & ~(smask << 16))
   1.291 -                                    | (svalue << 16);
   1.292 -                    break;
   1.293 -            }
   1.294 -        }
   1.295 -
   1.296 -        this.getDigit = function(index, shift) {
   1.297 -            return this.get16((index << 4) - shift);
   1.298 -        }
   1.299 -
   1.300 -        this.getTwoDigits = function(index, shift) {
   1.301 -            return this.get32(((index - 1) << 4) - shift);
   1.302 -        }
   1.303 -
   1.304 -        this.setDigit = function(index, shift, value) {
   1.305 -            this.set16((index << 4) - shift, value);
   1.306 -        }
   1.307 -
   1.308 -        this.countSignificantDigits = function() {
   1.309 -            var sd;
   1.310 -            var remaining;
   1.311 -
   1.312 -            if (this.hi32 === 0) {
   1.313 -                if (this.lo32 === 0) {
   1.314 -                    return 0;
   1.315 -                }
   1.316 -
   1.317 -                sd = 2;
   1.318 -                remaining = this.lo32;
   1.319 -            } else {
   1.320 -                sd = 4;
   1.321 -                remaining = this.hi32;
   1.322 -            }
   1.323 -
   1.324 -            if (remaining < 0) {
   1.325 -                return sd;
   1.326 -            }
   1.327 -
   1.328 -            return (remaining < 65536) ? sd - 1 : sd;
   1.329 -        }
   1.330 -        
   1.331 -        this.toNumber = function() {
   1.332 -            var lo32 = this.lo32;
   1.333 -            if (lo32 < 0) {
   1.334 -                lo32 += 0x100000000;
   1.335 -            }
   1.336 -
   1.337 -            return this.hi32.next32(lo32);
   1.338 -        }
   1.339 -    }
   1.340 -
   1.341 -    function __countLeadingZeroes16(number) {
   1.342 -        var nlz = 0;
   1.343 -
   1.344 -        if (number < 256) {
   1.345 -            nlz += 8;
   1.346 -            number <<= 8;
   1.347 -        }
   1.348 -
   1.349 -        if (number < 4096) {
   1.350 -            nlz += 4;
   1.351 -            number <<= 4;
   1.352 -        }
   1.353 -
   1.354 -        if (number < 16384) {
   1.355 -            nlz += 2;
   1.356 -            number <<= 2;
   1.357 -        }
   1.358 -
   1.359 -        return (number < 32768) ? nlz + 1 : nlz;
   1.360 -    }
   1.361 -    
   1.362 -    // q = u / v; r = u - q * v;
   1.363 -    // v != 0
   1.364 -    function __div64(q, r, u, v) {
   1.365 -        var m = u.countSignificantDigits();
   1.366 -        var n = v.countSignificantDigits();
   1.367 -
   1.368 -        q.hi32 = q.lo32 = 0;
   1.369 -
   1.370 -        if (n === 1) {
   1.371 -            // v has single digit
   1.372 -            var vd = v.getDigit(0, 0);
   1.373 -            var carry = 0;
   1.374 -            for (var i = m - 1; i >= 0; --i) {
   1.375 -                var ui = (carry << 16) | u.getDigit(i, 0);
   1.376 -                if (ui < 0) {
   1.377 -                    ui += 0x100000000;
   1.378 -                }
   1.379 -                var qi = (ui / vd) | 0;
   1.380 -                q.setDigit(i, 0, qi);
   1.381 -                carry = ui - qi * vd;
   1.382 -            }
   1.383 -
   1.384 -            r.hi32 = 0;
   1.385 -            r.lo32 = carry;
   1.386 -            return;
   1.387 -        }
   1.388 -
   1.389 -        r.hi32 = u.hi32;  
   1.390 -        r.lo32 = u.lo32;
   1.391 -
   1.392 -        if (m < n) {
   1.393 -            return;
   1.394 -        }
   1.395 -
   1.396 -        // Normalize
   1.397 -        var nrm = __countLeadingZeroes16(v.getDigit(n - 1, 0));
   1.398 -
   1.399 -        var vd1 = v.getDigit(n - 1, nrm);                
   1.400 -        var vd0 = v.getDigit(n - 2, nrm);
   1.401 -        for (var j = m - n; j >= 0; --j) {
   1.402 -            // Calculate qj estimate
   1.403 -            var ud21 = r.getTwoDigits(j + n, nrm);
   1.404 -            var ud2 = ud21 >>> 16;
   1.405 -            if (ud21 < 0) {
   1.406 -                ud21 += 0x100000000;
   1.407 -            }
   1.408 -
   1.409 -            var qest = (ud2 === vd1) ? 0xFFFF : ((ud21 / vd1) | 0);
   1.410 -            var rest = ud21 - qest * vd1;
   1.411 -
   1.412 -            // 0 <= (qest - qj) <= 2
   1.413 -
   1.414 -            // Refine qj estimate
   1.415 -            var ud0 = r.getDigit(j + n - 2, nrm);
   1.416 -            while ((qest * vd0) > ((rest * 0x10000) + ud0)) {
   1.417 -                --qest;
   1.418 -                rest += vd1;
   1.419 -            }
   1.420 -
   1.421 -            // 0 <= (qest - qj) <= 1
   1.422 -            
   1.423 -            // Multiply and subtract
   1.424 -            var carry = 0;
   1.425 -            for (var i = 0; i < n; ++i) {
   1.426 -                var vi = qest * v.getDigit(i, nrm);
   1.427 -                var ui = r.getDigit(i + j, nrm) - carry - (vi & 0xffff);
   1.428 -                r.setDigit(i + j, nrm, ui);
   1.429 -                carry = (vi >>> 16) - (ui >> 16);
   1.430 -            }
   1.431 -            var uj = ud2 - carry;
   1.432 -
   1.433 -            if (uj < 0) {
   1.434 -                // qest - qj = 1
   1.435 -
   1.436 -                // Add back
   1.437 -                --qest;
   1.438 -                var carry = 0;
   1.439 -                for (var i = 0; i < n; ++i) {
   1.440 -                    var ui = r.getDigit(i + j, nrm) + v.getDigit(i, nrm)
   1.441 -                                 + carry;
   1.442 -                    r.setDigit(i + j, nrm, ui);
   1.443 -                    carry = ui >> 16;
   1.444 -                }
   1.445 -                uj += carry;
   1.446 -            }
   1.447 -
   1.448 -            q.setDigit(j, 0, qest);
   1.449 -            r.setDigit(j + n, nrm, uj);
   1.450 -        }
   1.451 -    }
   1.452 -
   1.453 -    numberPrototype.div32 = function(x) {
   1.454 -        if (x === 0) {
   1.455 -            __handleDivByZero();
   1.456 -        }
   1.457 -
   1.458 -        return (this / x) | 0;
   1.459 -    }
   1.460 -
   1.461 -    numberPrototype.mod32 = function(x) {
   1.462 -        if (x === 0) {
   1.463 -            __handleDivByZero();
   1.464 -        }
   1.465 -
   1.466 -        return (this % x);
   1.467 -    }
   1.468 -
   1.469 -    numberPrototype.div64 = function(x) {
   1.470 -        var negateResult = false;
   1.471 -        var u, v;
   1.472 -
   1.473 -        if ((this.high32() & 0x80000000) != 0) {
   1.474 -            u = this.neg64();
   1.475 -            negateResult = !negateResult;
   1.476 -        } else {
   1.477 -            u = this;        
   1.478 -        }
   1.479 -
   1.480 -        if ((x.high32() & 0x80000000) != 0) {
   1.481 -            v = x.neg64();
   1.482 -            negateResult = !negateResult;
   1.483 -        } else {
   1.484 -            v = x;
   1.485 -        }
   1.486 -
   1.487 -        if ((v === 0) && (v.high32() === 0)) {
   1.488 -            __handleDivByZero();
   1.489 -        }
   1.490 -
   1.491 -        if (u.high32() === 0) {
   1.492 -            if (v.high32() === 0) {
   1.493 -                var result = (u / v) | 0;
   1.494 -                return negateResult ? result.neg64() : result; 
   1.495 -            }
   1.496 -
   1.497 -            return 0;
   1.498 -        }
   1.499 -
   1.500 -        var u64 = new __Int64(u.high32(), u);
   1.501 -        var v64 = new __Int64(v.high32(), v);
   1.502 -        var q64 = new __Int64(0, 0);
   1.503 -        var r64 = new __Int64(0, 0);
   1.504 -
   1.505 -        __div64(q64, r64, u64, v64);
   1.506 -
   1.507 -        var result = q64.toNumber();
   1.508 -        return negateResult ? result.neg64() : result; 
   1.509 -    }
   1.510 -
   1.511 -    numberPrototype.mod64 = function(x) {
   1.512 -        var negateResult = false;
   1.513 -        var u, v;
   1.514 -        
   1.515 -        if ((this.high32() & 0x80000000) != 0) {
   1.516 -            u = this.neg64();
   1.517 -            negateResult = !negateResult;
   1.518 -        } else {
   1.519 -            u = this;        
   1.520 -        }
   1.521 -
   1.522 -        if ((x.high32() & 0x80000000) != 0) {
   1.523 -            v = x.neg64();
   1.524 -        } else {
   1.525 -            v = x;
   1.526 -        }
   1.527 -
   1.528 -        if ((v === 0) && (v.high32() === 0)) {
   1.529 -            __handleDivByZero();
   1.530 -        }
   1.531 -
   1.532 -        if (u.high32() === 0) {
   1.533 -            var result = (v.high32() === 0) ? (u % v) : u;
   1.534 -            return negateResult ? result.neg64() : result; 
   1.535 -        }
   1.536 -
   1.537 -        var u64 = new __Int64(u.high32(), u);
   1.538 -        var v64 = new __Int64(v.high32(), v);
   1.539 -        var q64 = new __Int64(0, 0);
   1.540 -        var r64 = new __Int64(0, 0);
   1.541 -
   1.542 -        __div64(q64, r64, u64, v64);
   1.543 -
   1.544 -        var result = r64.toNumber();
   1.545 -        return negateResult ? result.neg64() : result; 
   1.546 -    }
   1.547 -})(Number.prototype);