Fix issue with Long.MIN_VALUE in Number.toExactString arithmetic
authorMartin Soch <Martin.Soch@oracle.com>
Thu, 07 Feb 2013 16:11:53 +0100
brancharithmetic
changeset 698ff57af563cb8
parent 689 f87c33d2fa7b
child 699 6cad41d877d2
Fix issue with Long.MIN_VALUE in Number.toExactString
Moved the first part of tests from vm/.../NumberTests to vmtest/.../LongArithmeticTest
emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js
vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java
vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java
vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java
     1.1 --- a/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js	Wed Feb 06 17:03:26 2013 +0100
     1.2 +++ b/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js	Thu Feb 07 16:11:53 2013 +0100
     1.3 @@ -33,6 +33,10 @@
     1.4  
     1.5  Number.prototype.toExactString = function() {
     1.6      if (this.hi) {
     1.7 +        // check for Long.MIN_VALUE
     1.8 +        if ((this.hi == (0x80000000 | 0)) && (this == 0)) {
     1.9 +            return '-9223372036854775808';
    1.10 +        }
    1.11          var res = 0;
    1.12          var a = [ 6,9,2,7,6,9,4,9,2,4 ];
    1.13          var s = '';
    1.14 @@ -60,7 +64,8 @@
    1.15              }
    1.16              s = String(digit).concat(s);
    1.17          }
    1.18 -        return (neg ? '-' : '').concat(res).concat(s);
    1.19 +        s = String(res).concat(s).replace(/^0+/, '');
    1.20 +        return (neg ? '-' : '').concat(s);
    1.21      }
    1.22      return String(this);
    1.23  };
     2.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java	Wed Feb 06 17:03:26 2013 +0100
     2.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java	Thu Feb 07 16:11:53 2013 +0100
     2.3 @@ -143,372 +143,6 @@
     2.4              s
     2.5          );
     2.6      }
     2.7 -    
     2.8 -    @Test public void longConversion() throws Exception {
     2.9 -        assertExec("Long from cPool",
    2.10 -            Numbers.class, "conversionL__J", 
    2.11 -            Double.valueOf(Long.MAX_VALUE)
    2.12 -        );
    2.13 -    }
    2.14 -    
    2.15 -    @Test public void longNegate1() throws Exception {
    2.16 -        final long res = -0x00fa37d7763e0ca1l;
    2.17 -        assertExec("Long negate",
    2.18 -            Numbers.class, "negL__J_3B", 
    2.19 -            Double.valueOf(res),
    2.20 -                new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 }
    2.21 -        );
    2.22 -    }
    2.23 -    
    2.24 -    @Test public void longNegate2() throws Exception {
    2.25 -        final long res = -0x80fa37d7763e0ca1l;
    2.26 -        assertExec("Long negate",
    2.27 -            Numbers.class, "negL__J_3B", 
    2.28 -            Double.valueOf(res),
    2.29 -                new byte[] { (byte)0x80, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 }
    2.30 -        );
    2.31 -    }
    2.32 -
    2.33 -    @Test public void longNegate3() throws Exception {
    2.34 -        final long res = -0xfffffffffffffeddl;
    2.35 -        assertExec("Long negate",
    2.36 -            Numbers.class, "negL__J_3B",
    2.37 -            Double.valueOf(res),
    2.38 -                new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
    2.39 -        );
    2.40 -    }
    2.41 -
    2.42 -    @Test public void longAddOverflow() throws Exception {
    2.43 -        final long res = Long.MAX_VALUE + 1l;
    2.44 -        assertExec("Addition 1+MAX",
    2.45 -            Numbers.class, "addL__J_3B_3B", 
    2.46 -            Double.valueOf(res),
    2.47 -                new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
    2.48 -                new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 }
    2.49 -        );
    2.50 -    }
    2.51 -    
    2.52 -    @Test public void longAddMaxAndMax() throws Exception {
    2.53 -        final long res = Long.MAX_VALUE + Long.MAX_VALUE;
    2.54 -        assertExec("Addition MAX+MAX",
    2.55 -            Numbers.class, "addL__J_3B_3B", 
    2.56 -            Double.valueOf(res),
    2.57 -            new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
    2.58 -            new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
    2.59 -        );
    2.60 -    }
    2.61 -    
    2.62 -    @Test public void longSubUnderflow() throws Exception {
    2.63 -        final long res = Long.MIN_VALUE - 1l;
    2.64 -        assertExec("Subtraction MIN-1",
    2.65 -            Numbers.class, "subL__J_3B_3B", 
    2.66 -            Double.valueOf(res),
    2.67 -                new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
    2.68 -                new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 }
    2.69 -        );
    2.70 -    }
    2.71 -    
    2.72 -    @Test public void longSubMinAndMin() throws Exception {
    2.73 -        final long res = Long.MIN_VALUE - Long.MIN_VALUE;
    2.74 -        assertExec("Subtraction MIN-MIN",
    2.75 -            Numbers.class, "subL__J_3B_3B", 
    2.76 -            Double.valueOf(res),
    2.77 -            new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
    2.78 -            new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
    2.79 -        );
    2.80 -    }
    2.81 -    
    2.82 -    @Test public void longSubMinAndMax() throws Exception {
    2.83 -        final long res = Long.MIN_VALUE - Long.MAX_VALUE;
    2.84 -        assertExec("Subtraction MIN-MAX",
    2.85 -            Numbers.class, "subL__J_3B_3B", 
    2.86 -            Double.valueOf(res),
    2.87 -            new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
    2.88 -            new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
    2.89 -        );
    2.90 -    }
    2.91 -    
    2.92 -    @Test public void longMultiplyMax() throws Exception {
    2.93 -        final long res = Long.MAX_VALUE * 2l;
    2.94 -        assertExec("Multiplication MAX*2",
    2.95 -            Numbers.class, "mulL__J_3B_3B",
    2.96 -            Double.valueOf(res),
    2.97 -            new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
    2.98 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02 }
    2.99 -        );
   2.100 -    }
   2.101 -    
   2.102 -    @Test public void longMultiplyMaxAndMax() throws Exception {
   2.103 -        final long res = Long.MAX_VALUE * Long.MAX_VALUE;
   2.104 -        assertExec("Multiplication MAX*MAX",
   2.105 -            Numbers.class, "mulL__J_3B_3B",
   2.106 -            Double.valueOf(res),
   2.107 -            new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   2.108 -            new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
   2.109 -        );
   2.110 -    }
   2.111 -    
   2.112 -    @Test public void longMultiplyMin() throws Exception {
   2.113 -        final long res = Long.MIN_VALUE * 2l;
   2.114 -        assertExec("Multiplication MIN*2",
   2.115 -            Numbers.class, "mulL__J_3B_3B",
   2.116 -            Double.valueOf(res),
   2.117 -            new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   2.118 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02 }
   2.119 -        );
   2.120 -    }
   2.121 -    
   2.122 -    @Test public void longMultiplyMinAndMin() throws Exception {
   2.123 -        final long res = Long.MIN_VALUE * Long.MIN_VALUE;
   2.124 -        assertExec("Multiplication MIN*2",
   2.125 -            Numbers.class, "mulL__J_3B_3B",
   2.126 -            Double.valueOf(res),
   2.127 -            new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   2.128 -            new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
   2.129 -        );
   2.130 -    }
   2.131 -    
   2.132 -    @Test public void longMultiplyPrecision() throws Exception {
   2.133 -        final long res = 0x00fa37d7763e0ca1l * 0xa7b3432fff00123el;
   2.134 -        assertExec("Multiplication",
   2.135 -            Numbers.class, "mulL__J_3B_3B",
   2.136 -            Double.valueOf(res),
   2.137 -            new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   2.138 -            new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   2.139 -        );
   2.140 -    }
   2.141 -
   2.142 -    @Test public void longDivideSmallPositiveNumbers() throws Exception {
   2.143 -        final long res = 0xabcdef / 0x123;
   2.144 -        assertExec("Division Small Positive Numbers",
   2.145 -            Numbers.class, "divL__J_3B_3B",
   2.146 -            Double.valueOf(res),
   2.147 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   2.148 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x23 }
   2.149 -        );
   2.150 -    }
   2.151 -
   2.152 -    @Test public void longDivideSmallNegativeNumbers() throws Exception {
   2.153 -        final long res = -0xabcdef / -0x123;
   2.154 -        assertExec("Division Small Negative Numbers",
   2.155 -            Numbers.class, "divL__J_3B_3B",
   2.156 -            Double.valueOf(res),
   2.157 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x11 },
   2.158 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   2.159 -        );
   2.160 -    }
   2.161 -
   2.162 -    @Test public void longDivideSmallMixedNumbers() throws Exception {
   2.163 -        final long res = 0xabcdef / -0x123;
   2.164 -        assertExec("Division Small Mixed Numbers",
   2.165 -            Numbers.class, "divL__J_3B_3B",
   2.166 -            Double.valueOf(res),
   2.167 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   2.168 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   2.169 -        );
   2.170 -    }
   2.171 -
   2.172 -    @Test public void longDividePositiveNumbersOneDigitDenom()
   2.173 -            throws Exception {
   2.174 -        final long res = 0xabcdef0102ffffL / 0x654;
   2.175 -        assertExec("Division Positive Numbers One Digit Denom",
   2.176 -            Numbers.class, "divL__J_3B_3B",
   2.177 -            Double.valueOf(res),
   2.178 -            new byte[] { (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0x01, (byte)0x02, (byte)0xff, (byte)0xff },
   2.179 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   2.180 -        );
   2.181 -    }
   2.182 -
   2.183 -    @Test public void longDivideNegativeNumbersOneDigitDenom()
   2.184 -            throws Exception {
   2.185 -        final long res = -0xabcdef0102ffffL / -0x654;
   2.186 -        assertExec("Division Negative Numbers One Digit Denom",
   2.187 -            Numbers.class, "divL__J_3B_3B",
   2.188 -            Double.valueOf(res),
   2.189 -            new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   2.190 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf9, (byte)0xac }
   2.191 -        );
   2.192 -    }
   2.193 -
   2.194 -    @Test public void longDivideMixedNumbersOneDigitDenom()
   2.195 -            throws Exception {
   2.196 -        final long res = -0xabcdef0102ffffL / 0x654;
   2.197 -        assertExec("Division Mixed Numbers One Digit Denom",
   2.198 -            Numbers.class, "divL__J_3B_3B",
   2.199 -            Double.valueOf(res),
   2.200 -            new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   2.201 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   2.202 -        );
   2.203 -    }
   2.204 -
   2.205 -    @Test public void longDividePositiveNumbersMultiDigitDenom()
   2.206 -            throws Exception {
   2.207 -        final long res = 0x7ffefc003322aabbL / 0x89ab1000L;
   2.208 -        assertExec("Division Positive Numbers Multi Digit Denom",
   2.209 -            Numbers.class, "divL__J_3B_3B",
   2.210 -            Double.valueOf(res),
   2.211 -            new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   2.212 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x89, (byte)0xab, (byte)0x10, (byte)0x00 }
   2.213 -        );
   2.214 -    }
   2.215 -
   2.216 -    @Test public void longDivideNegativeNumbersMultiDigitDenom()
   2.217 -            throws Exception {
   2.218 -        final long res = -0x7ffefc003322aabbL / -0x123489ab1001L;
   2.219 -        assertExec("Division Negative Numbers Multi Digit Denom",
   2.220 -            Numbers.class, "divL__J_3B_3B",
   2.221 -            Double.valueOf(res),
   2.222 -            new byte[] { (byte)0x80, (byte)0x01, (byte)0x03, (byte)0xff, (byte)0xcc, (byte)0xdd, (byte)0x55, (byte)0x45 },
   2.223 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xed, (byte)0xcb, (byte)0x76, (byte)0x54, (byte)0xef, (byte)0xff }
   2.224 -        );
   2.225 -    }
   2.226 -
   2.227 -    @Test public void longDivideMixedNumbersMultiDigitDenom()
   2.228 -            throws Exception {
   2.229 -        final long res = 0x7ffefc003322aabbL / -0x38f49b0b7574e36L;
   2.230 -        assertExec("Division Mixed Numbers Multi Digit Denom",
   2.231 -            Numbers.class, "divL__J_3B_3B",
   2.232 -            Double.valueOf(res),
   2.233 -            new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   2.234 -            new byte[] { (byte)0xfc, (byte)0x70, (byte)0xb6, (byte)0x4f, (byte)0x48, (byte)0xa8, (byte)0xb1, (byte)0xca }
   2.235 -        );
   2.236 -    }
   2.237 -
   2.238 -    @Test public void longDivideWithOverflow() throws Exception {
   2.239 -        final long res = 0x8000fffe0000L / 0x8000ffffL;
   2.240 -        assertExec("Division With Overflow",
   2.241 -            Numbers.class, "divL__J_3B_3B",
   2.242 -            Double.valueOf(res),
   2.243 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 },
   2.244 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xff }
   2.245 -        );
   2.246 -    }
   2.247 -
   2.248 -    @Test public void longDivideWithCorrection() throws Exception {
   2.249 -        final long res = 0x7fff800000000000L / 0x800000000001L;
   2.250 -        assertExec("Division With Correction",
   2.251 -            Numbers.class, "divL__J_3B_3B",
   2.252 -            Double.valueOf(res),
   2.253 -            new byte[] { (byte)0x7f, (byte)0xff, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   2.254 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 }
   2.255 -        );
   2.256 -    }
   2.257 -
   2.258 -    @Test public void longModuloSmallPositiveNumbers() throws Exception {
   2.259 -        final long res = 0xabcdef % 0x123;
   2.260 -        assertExec("Modulo Small Positive Numbers",
   2.261 -            Numbers.class, "modL__J_3B_3B",
   2.262 -            Double.valueOf(res),
   2.263 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   2.264 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x23 }
   2.265 -        );
   2.266 -    }
   2.267 -
   2.268 -    @Test public void longModuloSmallNegativeNumbers() throws Exception {
   2.269 -        final long res = -0xabcdef % -0x123;
   2.270 -        assertExec("Modulo Small Negative Numbers",
   2.271 -            Numbers.class, "modL__J_3B_3B",
   2.272 -            Double.valueOf(res),
   2.273 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x11 },
   2.274 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   2.275 -        );
   2.276 -    }
   2.277 -
   2.278 -    @Test public void longModuloSmallMixedNumbers() throws Exception {
   2.279 -        final long res = 0xabcdef % -0x123;
   2.280 -        assertExec("Modulo Small Mixed Numbers",
   2.281 -            Numbers.class, "modL__J_3B_3B",
   2.282 -            Double.valueOf(res),
   2.283 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   2.284 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   2.285 -        );
   2.286 -    }
   2.287 -
   2.288 -    @Test public void longModuloPositiveNumbersOneDigitDenom()
   2.289 -            throws Exception {
   2.290 -        final long res = 0xabcdef0102ffffL % 0x654;
   2.291 -        assertExec("Modulo Positive Numbers One Digit Denom",
   2.292 -            Numbers.class, "modL__J_3B_3B",
   2.293 -            Double.valueOf(res),
   2.294 -            new byte[] { (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0x01, (byte)0x02, (byte)0xff, (byte)0xff },
   2.295 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   2.296 -        );
   2.297 -    }
   2.298 -
   2.299 -    @Test public void longModuloNegativeNumbersOneDigitDenom()
   2.300 -            throws Exception {
   2.301 -        final long res = -0xabcdef0102ffffL % -0x654;
   2.302 -        assertExec("Modulo Negative Numbers One Digit Denom",
   2.303 -            Numbers.class, "modL__J_3B_3B",
   2.304 -            Double.valueOf(res),
   2.305 -            new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   2.306 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf9, (byte)0xac }
   2.307 -        );
   2.308 -    }
   2.309 -
   2.310 -    @Test public void longModuloMixedNumbersOneDigitDenom()
   2.311 -            throws Exception {
   2.312 -        final long res = -0xabcdef0102ffffL % 0x654;
   2.313 -        assertExec("Modulo Mixed Numbers One Digit Denom",
   2.314 -            Numbers.class, "modL__J_3B_3B",
   2.315 -            Double.valueOf(res),
   2.316 -            new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   2.317 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   2.318 -        );
   2.319 -    }
   2.320 -
   2.321 -    @Test public void longModuloPositiveNumbersMultiDigitDenom()
   2.322 -            throws Exception {
   2.323 -        final long res = 0x7ffefc003322aabbL % 0x89ab1000L;
   2.324 -        assertExec("Modulo Positive Numbers Multi Digit Denom",
   2.325 -            Numbers.class, "modL__J_3B_3B",
   2.326 -            Double.valueOf(res),
   2.327 -            new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   2.328 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x89, (byte)0xab, (byte)0x10, (byte)0x00 }
   2.329 -        );
   2.330 -    }
   2.331 -
   2.332 -    @Test public void longModuloNegativeNumbersMultiDigitDenom()
   2.333 -            throws Exception {
   2.334 -        final long res = -0x7ffefc003322aabbL % -0x123489ab1001L;
   2.335 -        assertExec("Modulo Negative Numbers Multi Digit Denom",
   2.336 -            Numbers.class, "modL__J_3B_3B",
   2.337 -            Double.valueOf(res),
   2.338 -            new byte[] { (byte)0x80, (byte)0x01, (byte)0x03, (byte)0xff, (byte)0xcc, (byte)0xdd, (byte)0x55, (byte)0x45 },
   2.339 -            new byte[] { (byte)0xff, (byte)0xff, (byte)0xed, (byte)0xcb, (byte)0x76, (byte)0x54, (byte)0xef, (byte)0xff }
   2.340 -        );
   2.341 -    }
   2.342 -
   2.343 -    @Test public void longModuloMixedNumbersMultiDigitDenom()
   2.344 -            throws Exception {
   2.345 -        final long res = 0x7ffefc003322aabbL % -0x38f49b0b7574e36L;
   2.346 -        assertExec("Modulo Mixed Numbers Multi Digit Denom",
   2.347 -            Numbers.class, "modL__J_3B_3B",
   2.348 -            Double.valueOf(res),
   2.349 -            new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   2.350 -            new byte[] { (byte)0xfc, (byte)0x70, (byte)0xb6, (byte)0x4f, (byte)0x48, (byte)0xa8, (byte)0xb1, (byte)0xca }
   2.351 -        );
   2.352 -    }
   2.353 -
   2.354 -    @Test public void longModuloWithOverflow() throws Exception {
   2.355 -        final long res = 0x8000fffe0000L % 0x8000ffffL;
   2.356 -        assertExec("Modulo With Overflow",
   2.357 -            Numbers.class, "modL__J_3B_3B",
   2.358 -            Double.valueOf(res),
   2.359 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 },
   2.360 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xff }
   2.361 -        );
   2.362 -    }
   2.363 -
   2.364 -    @Test public void longModuloWithCorrection() throws Exception {
   2.365 -        final long res = 0x7fff800000000000L % 0x800000000001L;
   2.366 -        assertExec("Modulo With Correction",
   2.367 -            Numbers.class, "modL__J_3B_3B",
   2.368 -            Double.valueOf(res),
   2.369 -            new byte[] { (byte)0x7f, (byte)0xff, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   2.370 -            new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 }
   2.371 -        );
   2.372 -    }
   2.373  
   2.374      @Test public void longShiftL1() throws Exception {
   2.375          final long res = 0x00fa37d7763e0ca1l << 5;
     3.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java	Wed Feb 06 17:03:26 2013 +0100
     3.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java	Thu Feb 07 16:11:53 2013 +0100
     3.3 @@ -68,56 +68,6 @@
     3.4          return new Float(7.0).toString().toString();
     3.5      }
     3.6      
     3.7 -    public static long conversionL() {
     3.8 -        return Long.MAX_VALUE;
     3.9 -    }
    3.10 -    
    3.11 -    public static long negL(byte[] arrValue) throws IOException {
    3.12 -        ByteArrayInputStream isValue = new ByteArrayInputStream(arrValue);
    3.13 -        DataInputStream disValue = new DataInputStream(isValue);
    3.14 -        return (-disValue.readLong());
    3.15 -    }
    3.16 -    
    3.17 -    public static long addL(byte[] arrX, byte[] arrY) throws IOException {
    3.18 -        ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
    3.19 -        DataInputStream disX = new DataInputStream(isX);
    3.20 -        ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
    3.21 -        DataInputStream disY = new DataInputStream(isY);
    3.22 -        return (disX.readLong() + disY.readLong());
    3.23 -    }
    3.24 -    
    3.25 -    public static long subL(byte[] arrX, byte[] arrY) throws IOException {
    3.26 -        ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
    3.27 -        DataInputStream disX = new DataInputStream(isX);
    3.28 -        ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
    3.29 -        DataInputStream disY = new DataInputStream(isY);
    3.30 -        return (disX.readLong() - disY.readLong());
    3.31 -    }
    3.32 -    
    3.33 -    public static long mulL(byte[] arrX, byte[] arrY) throws IOException {
    3.34 -        ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
    3.35 -        DataInputStream disX = new DataInputStream(isX);
    3.36 -        ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
    3.37 -        DataInputStream disY = new DataInputStream(isY);
    3.38 -        return (disX.readLong() * disY.readLong());
    3.39 -    }
    3.40 -    
    3.41 -    public static long divL(byte[] arrX, byte[] arrY) throws IOException {
    3.42 -        ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
    3.43 -        DataInputStream disX = new DataInputStream(isX);
    3.44 -        ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
    3.45 -        DataInputStream disY = new DataInputStream(isY);
    3.46 -        return (disX.readLong() / disY.readLong());
    3.47 -    }
    3.48 -    
    3.49 -    public static long modL(byte[] arrX, byte[] arrY) throws IOException {
    3.50 -        ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
    3.51 -        DataInputStream disX = new DataInputStream(isX);
    3.52 -        ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
    3.53 -        DataInputStream disY = new DataInputStream(isY);
    3.54 -        return (disX.readLong() % disY.readLong());
    3.55 -    }
    3.56 -    
    3.57      public static long shlL(byte[] arrValue, int nBits) throws IOException {
    3.58          ByteArrayInputStream isValue = new ByteArrayInputStream(arrValue);
    3.59          DataInputStream disValue = new DataInputStream(isValue);
     4.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java	Wed Feb 06 17:03:26 2013 +0100
     4.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java	Thu Feb 07 16:11:53 2013 +0100
     4.3 @@ -47,19 +47,34 @@
     4.4          return (x % y);
     4.5      }
     4.6      
     4.7 +    private static long neg(long x) {
     4.8 +        return -x;
     4.9 +    }
    4.10 +    
    4.11      @Compare public long conversion() {
    4.12          return Long.MAX_VALUE;
    4.13      }
    4.14      
    4.15 -    /*
    4.16 +    @Compare public long negate1() {
    4.17 +        return neg(0x00fa37d7763e0ca1l);
    4.18 +    }
    4.19 +    
    4.20 +    @Compare public long negate2() {
    4.21 +        return neg(0x80fa37d7763e0ca1l);
    4.22 +    }
    4.23 +
    4.24 +    @Compare public long negate3() {
    4.25 +        return neg(0xfffffffffffffeddl);
    4.26 +    }
    4.27 +
    4.28      @Compare public long addOverflow() {
    4.29          return add(Long.MAX_VALUE, 1l);
    4.30      }
    4.31 -    
    4.32 +
    4.33      @Compare public long subUnderflow() {
    4.34          return sub(Long.MIN_VALUE, 1l);
    4.35      }
    4.36 -    
    4.37 +
    4.38      @Compare public long addMaxLongAndMaxLong() {
    4.39          return add(Long.MAX_VALUE, Long.MAX_VALUE);
    4.40      }
    4.41 @@ -68,6 +83,10 @@
    4.42          return sub(Long.MIN_VALUE, Long.MIN_VALUE);
    4.43      }
    4.44      
    4.45 +    @Compare public long subMinLongAndMaxLong() {
    4.46 +        return sub(Long.MIN_VALUE, Long.MAX_VALUE);
    4.47 +    }
    4.48 +
    4.49      @Compare public long multiplyMaxLong() {
    4.50          return mul(Long.MAX_VALUE, 2l);
    4.51      }
    4.52 @@ -85,17 +104,96 @@
    4.53      }
    4.54      
    4.55      @Compare public long multiplyPrecision() {
    4.56 -        return mul(17638l, 1103l);
    4.57 +        return mul(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el);
    4.58      }
    4.59      
    4.60 -    @Compare public long division() {
    4.61 -        return div(1l, 2l);
    4.62 +    @Compare public long divideSmallPositiveNumbers() {
    4.63 +        return div(0xabcdef, 0x123);
    4.64      }
    4.65 -    
    4.66 -    @Compare public long divisionReminder() {
    4.67 -        return mod(1l, 2l);
    4.68 +
    4.69 +    @Compare public long divideSmallNegativeNumbers() {
    4.70 +        return div(-0xabcdef, -0x123);
    4.71      }
    4.72 -    */
    4.73 +
    4.74 +    @Compare public long divideSmallMixedNumbers() {
    4.75 +        return div(0xabcdef, -0x123);
    4.76 +    }
    4.77 +
    4.78 +    @Compare public long dividePositiveNumbersOneDigitDenom() {
    4.79 +        return div(0xabcdef0102ffffl, 0x654);
    4.80 +    }
    4.81 +
    4.82 +    @Compare public long divideNegativeNumbersOneDigitDenom() {
    4.83 +        return div(-0xabcdef0102ffffl, -0x654);
    4.84 +    }
    4.85 +
    4.86 +    @Compare public long divideMixedNumbersOneDigitDenom() {
    4.87 +        return div(-0xabcdef0102ffffl, 0x654);
    4.88 +    }
    4.89 +
    4.90 +    @Compare public long dividePositiveNumbersMultiDigitDenom() {
    4.91 +        return div(0x7ffefc003322aabbl, 0x89ab1000l);
    4.92 +    }
    4.93 +
    4.94 +    @Compare public long divideNegativeNumbersMultiDigitDenom() {
    4.95 +        return div(-0x7ffefc003322aabbl, -0x123489ab1001l);
    4.96 +    }
    4.97 +
    4.98 +    @Compare public long divideMixedNumbersMultiDigitDenom() {
    4.99 +        return div(0x7ffefc003322aabbl, -0x38f49b0b7574e36l);
   4.100 +    }
   4.101 +
   4.102 +    @Compare public long divideWithOverflow() {
   4.103 +        return div(0x8000fffe0000l, 0x8000ffffl);
   4.104 +    }
   4.105 +
   4.106 +    @Compare public long divideWithCorrection() {
   4.107 +        return div(0x7fff800000000000l, 0x800000000001l);
   4.108 +    }
   4.109 +
   4.110 +    @Compare public long moduloSmallPositiveNumbers() {
   4.111 +        return mod(0xabcdef, 0x123);
   4.112 +    }
   4.113 +
   4.114 +    @Compare public long moduloSmallNegativeNumbers() {
   4.115 +        return mod(-0xabcdef, -0x123);
   4.116 +    }
   4.117 +
   4.118 +    @Compare public long moduloSmallMixedNumbers() {
   4.119 +        return mod(0xabcdef, -0x123);
   4.120 +    }
   4.121 +
   4.122 +    @Compare public long moduloPositiveNumbersOneDigitDenom() {
   4.123 +        return mod(0xabcdef0102ffffl, 0x654);
   4.124 +    }
   4.125 +
   4.126 +    @Compare public long moduloNegativeNumbersOneDigitDenom() {
   4.127 +        return mod(-0xabcdef0102ffffl, -0x654);
   4.128 +    }
   4.129 +
   4.130 +    @Compare public long moduloMixedNumbersOneDigitDenom() {
   4.131 +        return mod(-0xabcdef0102ffffl, 0x654);
   4.132 +    }
   4.133 +
   4.134 +    @Compare public long moduloPositiveNumbersMultiDigitDenom() {
   4.135 +        return mod(0x7ffefc003322aabbl, 0x89ab1000l);
   4.136 +    }
   4.137 +
   4.138 +    @Compare public long moduloNegativeNumbersMultiDigitDenom() {
   4.139 +        return mod(-0x7ffefc003322aabbl, -0x123489ab1001l);
   4.140 +    }
   4.141 +
   4.142 +    @Compare public long moduloMixedNumbersMultiDigitDenom() {
   4.143 +        return mod(0x7ffefc003322aabbl, -0x38f49b0b7574e36l);
   4.144 +    }
   4.145 +
   4.146 +    @Compare public long moduloWithOverflow() {
   4.147 +        return mod(0x8000fffe0000l, 0x8000ffffl);
   4.148 +    }
   4.149 +
   4.150 +    @Compare public long moduloWithCorrection() {
   4.151 +        return mod(0x7fff800000000000l, 0x800000000001l);
   4.152 +    }
   4.153      
   4.154      @Factory
   4.155      public static Object[] create() {