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