emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js
author Martin Soch <Martin.Soch@oracle.com>
Tue, 05 Feb 2013 15:03:22 +0100
brancharithmetic
changeset 669 3754580b6c67
parent 657 b42bfe334128
child 675 7d3da112e2c1
permissions -rw-r--r--
Fixed error in neg64 found bu Lubo.
     1 // empty line needed here
     2 Number.prototype.add32 = function(x) { return (this + x) | 0; };
     3 Number.prototype.sub32 = function(x) { return (this - x) | 0; };
     4 Number.prototype.mul32 = function(x) { 
     5     return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
     6 };
     7 
     8 Number.prototype.toInt8 = function()  { return (this << 24) >> 24; };
     9 Number.prototype.toInt16 = function() { return (this << 16) >> 16; };
    10 
    11 var __m32 = 0xFFFFFFFF;
    12 
    13 Number.prototype.next32 = function(low) {
    14   if (this === 0) {
    15     return low;
    16   }
    17   var l = new Number(low);
    18   l.hi = this | 0;
    19   return l;
    20 };
    21 
    22 Number.prototype.high32 = function() { 
    23     return this.hi ? this.hi : (Math.floor(this / (__m32+1))) | 0;
    24 };
    25 Number.prototype.toInt32 = function() { return this | 0; };
    26 Number.prototype.toFP = function() {
    27     return this.hi ? this.hi * (__m32+1) + this : this;
    28 };
    29 Number.prototype.toLong = function() {
    30     var hi = (this > __m32) ? (Math.floor(this / (__m32+1))) | 0 : 0;
    31     return hi.next32(Math.floor(this % (__m32+1)));
    32 };
    33 
    34 Number.prototype.toExactString = function() {
    35     if (this.hi) {
    36         var res = 0;
    37         var a = [ 6,9,2,7,6,9,4,9,2,4 ];
    38         var s = '';
    39         var digit;
    40         var hi = this.hi;
    41         var low = this;
    42         for (var i = 0; i < a.length; i++) {
    43             res += hi * a[i];
    44             var low_digit = low % 10;
    45             digit = (res % 10) + low_digit;
    46 
    47             low = Math.floor(low / 10);
    48             res = Math.floor(res / 10);
    49 
    50             if (digit >= 10) {
    51                 digit -= 10;
    52                 res++;
    53             }
    54             s = String(digit).concat(s);
    55         }
    56         return String(res).concat(s);
    57     }
    58     return String(this);
    59 };
    60 
    61 Number.prototype.add64 = function(x) {
    62     var low = this + x;
    63     carry = 0;
    64     if (low > __m32) {
    65         carry = 1;
    66         low -= (__m32+1);
    67     }
    68     var hi = (this.high32() + x.high32() + carry) | 0;
    69     return hi.next32(low);
    70 };
    71 
    72 Number.prototype.sub64 = function(x) {
    73     var low = this - x;
    74     carry = 0;
    75     if (low < 0) {
    76         carry = 1;
    77         low += (__m32+1);
    78     }
    79     var hi = (this.high32() - x.high32() - carry) | 0;
    80     return hi.next32(low);
    81 };
    82 
    83 Number.prototype.mul64 = function(x) {
    84     var low = this.mul32(x);
    85     low += (low < 0) ? (__m32+1) : 0;
    86     // first count upper 32 bits of (this.low * x.low)
    87     var hi_hi = 0;
    88     var hi_low = 0;
    89     var m = 1;
    90     for (var i = 0; i < 32; i++) {
    91         if (x & m) {
    92             hi_hi += this >>> 16;
    93             hi_low += this & 0xFFFF
    94         }
    95         hi_low >>= 1;
    96         hi_low += (hi_hi & 1) ? 0x8000 : 0;
    97         hi_hi >>= 1;
    98         m <<= 1;
    99     }
   100     var hi = (hi_hi << 16) + hi_low;
   101     
   102     var m1 = this.high32().mul32(x);
   103     var m2 = this.mul32(x.high32());
   104     hi = hi.add32(m1).add32(m2);
   105     
   106     return hi.next32(low);
   107 };
   108 
   109 Number.prototype.div64 = function(x) {
   110     var low = Math.floor(this.toFP() / x.toFP()); // TODO: not exact enough
   111     if (low > __m32) {
   112         var hi = Math.floor(low / (__m32+1)) | 0;
   113         return hi.next32(low % (__m32+1));
   114     }
   115     return low;
   116 };
   117 
   118 Number.prototype.and64 = function(x) {
   119     var low = this & x;
   120     low += (low < 0) ? (__m32+1) : 0;
   121     if (this.hi && x.hi) {
   122         var hi = this.hi & x.hi;
   123         return hi.next32(low);
   124     };
   125     return low;
   126 };
   127 
   128 Number.prototype.or64 = function(x) {
   129     var low = this | x;
   130     low += (low < 0) ? (__m32+1) : 0;
   131     if (this.hi || x.hi) {
   132         var hi = this.hi | x.hi;
   133         return hi.next32(low);
   134     };
   135     return low;
   136 };
   137 
   138 Number.prototype.xor64 = function(x) {
   139     var low = this ^ x;
   140     low += (low < 0) ? (__m32+1) : 0;
   141     if (this.hi || x.hi) {
   142         var hi = this.hi ^ x.hi;
   143         return hi.next32(low);
   144     };
   145     return low;
   146 };
   147 
   148 Number.prototype.shl64 = function(x) {
   149     if (x >= 32) {
   150         var hi = this << (x - 32);
   151         return hi.next32(0);
   152     } else {
   153         var hi = this.high32() << x;
   154         var low_reminder = this >> (32 - x);
   155         hi |= low_reminder;
   156         var low = this << x;
   157         low += (low < 0) ? (__m32+1) : 0;
   158         return hi.next32(low);
   159     }
   160 };
   161 
   162 Number.prototype.shr64 = function(x) {
   163     if (x >= 32) {
   164         var low = this.high32() >> (x - 32);
   165         low += (low < 0) ? (__m32+1) : 0;
   166         return low;
   167     } else {
   168         var low = this >> x;
   169         var hi_reminder = this.high32() << (32 - x);
   170         low |= hi_reminder;
   171         low += (low < 0) ? (__m32+1) : 0;
   172         var hi = this.high32() >> x;
   173         return hi.next32(low);
   174     }
   175 };
   176 
   177 Number.prototype.ushr64 = function(x) {
   178     if (x >= 32) {
   179         var low = this.high32() >>> (x - 32);
   180         low += (low < 0) ? (__m32+1) : 0;
   181         return low;
   182     } else {
   183         var low = this >>> x;
   184         var hi_reminder = this.high32() << (32 - x);
   185         low |= hi_reminder;
   186         low += (low < 0) ? (__m32+1) : 0;
   187         var hi = this.high32() >>> x;
   188         return hi.next32(low);
   189     }
   190 };
   191 
   192 Number.prototype.compare64 = function(x) {
   193     if (this.hi == x.hi) {
   194         return (this == x) ? 0 : ((this < x) ? -1 : 1);
   195     }
   196     return (this.hi < x.hi) ? -1 : 1;
   197 };
   198 
   199 Number.prototype.neg64 = function() {
   200     var hi = this.high32();
   201     var low = this;
   202     if ((hi === 0) && (low < 0)) { return -low; }
   203     hi = ~hi;
   204     low = ~low;
   205     low += (low < 0) ? (__m32+1) : 0;
   206     var ret = hi.next32(low);
   207     return ret.add64(1);
   208 };