vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java
author Lubomir Nerad <lubomir.nerad@oracle.com>
Tue, 05 Feb 2013 16:40:01 +0100
brancharithmetic
changeset 676 eecf6077ec4e
parent 669 3754580b6c67
child 680 7ffb635a5c4f
permissions -rw-r--r--
Support for Long division + tests
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.vm4brwsr;
    19 
    20 import javax.script.Invocable;
    21 import javax.script.ScriptException;
    22 import static org.testng.Assert.*;
    23 import org.testng.annotations.BeforeClass;
    24 import org.testng.annotations.Test;
    25 
    26 /**
    27  *
    28  * @author Jaroslav Tulach <jtulach@netbeans.org>
    29  */
    30 public class NumberTest {
    31     @Test public void integerFromString() throws Exception {
    32         assertExec("Can convert string to integer", Integer.class, "parseInt__ILjava_lang_String_2",
    33             Double.valueOf(333), "333"
    34         );
    35     }
    36 
    37     @Test public void doubleFromString() throws Exception {
    38         assertExec("Can convert string to double", Double.class, "parseDouble__DLjava_lang_String_2",
    39             Double.valueOf(33.3), "33.3"
    40         );
    41     }
    42 
    43     @Test public void autoboxDouble() throws Exception {
    44         assertExec("Autoboxing of doubles is OK", Numbers.class, "autoboxDblToString__Ljava_lang_String_2",
    45             "3.3"
    46         );
    47     }
    48     
    49     @Test public void javalog1000() throws Exception {
    50         assertEquals(3.0, Math.log10(1000.0), 0.00003, "log_10(1000) == 3");
    51     }
    52 
    53     @Test public void jslog1000() throws Exception {
    54         assertExec("log_10(1000) == 3", Math.class, "log10__DD", 
    55             Double.valueOf(3.0), 1000.0
    56         );
    57     }
    58     
    59     @Test public void javaRem() {
    60         assertEquals(3, Numbers.rem(303, 10));
    61     }
    62     @Test public void jsRem() throws Exception {
    63         assertExec("Should be three", Numbers.class, "rem__III", 
    64             Double.valueOf(3.0), 303, 10
    65         );
    66     }
    67     
    68     @Test public void deserializeInt() throws Exception {
    69         int exp = Numbers.deserInt();
    70         assertExec("Should be the same", Numbers.class, "deserInt__I", 
    71             Double.valueOf(exp)
    72         );
    73     }
    74 
    75     @Test public void deserializeSimpleLong() throws Exception {
    76         assertExec("Should be 3454", Numbers.class, "deserLong__J_3B", 
    77             Double.valueOf(3454), 
    78             new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)13, (byte)126 }
    79         );
    80     }
    81     /* XXX: JavaScript cannot represent as big longs as Java. 
    82     @Test public void deserializeLargeLong() throws Exception {
    83         final byte[] arr = new byte[] {
    84             (byte)64, (byte)8, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0
    85         };
    86         long exp = Numbers.deserLong(arr);
    87         assertExec("Should be " + exp, "org_apidesign_vm4brwsr_Numbers_deserLong__JAB", 
    88             Double.valueOf(exp), arr);
    89     }
    90     */
    91     
    92     @Test public void deserializeFloatInJava() throws Exception {
    93         float f = 54324.32423f;
    94         float r = Numbers.deserFloat();
    95         assertEquals(r, f, "Floats are the same");
    96     }
    97     
    98     @Test public void deserializeFloatInJS() throws Exception {
    99         float f = 54324.32423f;
   100         assertExec("Should be the same", Numbers.class, "deserFloat__F", 
   101             Double.valueOf(f)
   102         );
   103     }
   104 
   105     @Test public void deserializeDoubleInJava() throws Exception {
   106         double f = 3.0;
   107         double r = Numbers.deserDouble();
   108         assertEquals(r, f, 0.001, "Doubles are the same");
   109     }
   110     
   111     @Test public void deserializeDoubleInJS() throws Exception {
   112         double f = 3.0;
   113         assertExec("Should be the same", Numbers.class, "deserDouble__D", f);
   114     }
   115     /*
   116     @Test public void serDouble() throws IOException {
   117         double f = 3.0;
   118         ByteArrayOutputStream os = new ByteArrayOutputStream();
   119         DataOutputStream d = new DataOutputStream(os);
   120         d.writeLong(3454);
   121         d.close();
   122         
   123         StringBuilder sb = new StringBuilder();
   124         byte[] arr = os.toByteArray();
   125         for (int i = 0; i < arr.length; i++) {
   126             sb.append("(byte)").append(arr[i]).append(", ");
   127         }
   128         fail("" + sb);
   129     }
   130 */    
   131     @Test public void fiveInStringJS() throws Exception {
   132         String s = Numbers.intToString();
   133         assertExec("Should be the same: " + s, 
   134             Numbers.class, "intToString__Ljava_lang_String_2", 
   135             s
   136         );
   137     }
   138 
   139     @Test public void sevenInStringJS() throws Exception {
   140         String s = Numbers.floatToString();
   141         assertExec("Should be the same: " + s, 
   142             Numbers.class, "floatToString__Ljava_lang_String_2", 
   143             s
   144         );
   145     }
   146     
   147     @Test public void longConversion() throws Exception {
   148         assertExec("Long from cPool",
   149             Numbers.class, "conversionL__J", 
   150             Double.valueOf(Long.MAX_VALUE)
   151         );
   152     }
   153     
   154     @Test public void longNegate1() throws Exception {
   155         final long res = -0x00fa37d7763e0ca1l;
   156         assertExec("Long negate",
   157             Numbers.class, "negL__J_3B", 
   158             Double.valueOf(res),
   159                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 }
   160         );
   161     }
   162     
   163     @Test public void longNegate2() throws Exception {
   164         final long res = -0x80fa37d7763e0ca1l;
   165         assertExec("Long negate",
   166             Numbers.class, "negL__J_3B", 
   167             Double.valueOf(res),
   168                 new byte[] { (byte)0x80, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 }
   169         );
   170     }
   171 
   172     @Test public void longNegate3() throws Exception {
   173         final long res = -0xfffffffffffffeddl;
   174         assertExec("Long negate",
   175             Numbers.class, "negL__J_3B",
   176             Double.valueOf(res),
   177                 new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   178         );
   179     }
   180 
   181     @Test public void longAddOverflow() throws Exception {
   182         final long res = Long.MAX_VALUE + 1l;
   183         assertExec("Addition 1+MAX",
   184             Numbers.class, "addL__J_3B_3B", 
   185             Double.valueOf(res),
   186                 new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   187                 new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 }
   188         );
   189     }
   190     
   191     @Test public void longAddMaxAndMax() throws Exception {
   192         final long res = Long.MAX_VALUE + Long.MAX_VALUE;
   193         assertExec("Addition MAX+MAX",
   194             Numbers.class, "addL__J_3B_3B", 
   195             Double.valueOf(res),
   196             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   197             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
   198         );
   199     }
   200     
   201     @Test public void longSubUnderflow() throws Exception {
   202         final long res = Long.MIN_VALUE - 1l;
   203         assertExec("Subtraction MIN-1",
   204             Numbers.class, "subL__J_3B_3B", 
   205             Double.valueOf(res),
   206                 new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   207                 new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 }
   208         );
   209     }
   210     
   211     @Test public void longSubMinAndMin() throws Exception {
   212         final long res = Long.MIN_VALUE - Long.MIN_VALUE;
   213         assertExec("Subtraction MIN-MIN",
   214             Numbers.class, "subL__J_3B_3B", 
   215             Double.valueOf(res),
   216             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   217             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
   218         );
   219     }
   220     
   221     @Test public void longSubMinAndMax() throws Exception {
   222         final long res = Long.MIN_VALUE - Long.MAX_VALUE;
   223         assertExec("Subtraction MIN-MAX",
   224             Numbers.class, "subL__J_3B_3B", 
   225             Double.valueOf(res),
   226             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   227             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
   228         );
   229     }
   230     
   231     @Test public void longMultiplyMax() throws Exception {
   232         final long res = Long.MAX_VALUE * 2l;
   233         assertExec("Multiplication MAX*2",
   234             Numbers.class, "mulL__J_3B_3B",
   235             Double.valueOf(res),
   236             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   237             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02 }
   238         );
   239     }
   240     
   241     @Test public void longMultiplyMaxAndMax() throws Exception {
   242         final long res = Long.MAX_VALUE * Long.MAX_VALUE;
   243         assertExec("Multiplication MAX*MAX",
   244             Numbers.class, "mulL__J_3B_3B",
   245             Double.valueOf(res),
   246             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
   247             new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
   248         );
   249     }
   250     
   251     @Test public void longMultiplyMin() throws Exception {
   252         final long res = Long.MIN_VALUE * 2l;
   253         assertExec("Multiplication MIN*2",
   254             Numbers.class, "mulL__J_3B_3B",
   255             Double.valueOf(res),
   256             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   257             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02 }
   258         );
   259     }
   260     
   261     @Test public void longMultiplyMinAndMin() throws Exception {
   262         final long res = Long.MIN_VALUE * Long.MIN_VALUE;
   263         assertExec("Multiplication MIN*2",
   264             Numbers.class, "mulL__J_3B_3B",
   265             Double.valueOf(res),
   266             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   267             new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
   268         );
   269     }
   270     
   271     @Test public void longMultiplyPrecision() throws Exception {
   272         final long res = 0x00fa37d7763e0ca1l * 0xa7b3432fff00123el;
   273         assertExec("Multiplication",
   274             Numbers.class, "mulL__J_3B_3B",
   275             Double.valueOf(res),
   276             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   277             new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   278         );
   279     }
   280 
   281     @Test public void longDivideSmallPositiveNumbers() throws Exception {
   282         final long res = 0xabcdef / 0x123;
   283         assertExec("Division Small Positive Numbers",
   284             Numbers.class, "divL__J_3B_3B",
   285             Double.valueOf(res),
   286             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   287             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x23 }
   288         );
   289     }
   290 
   291     @Test public void longDivideSmallNegativeNumbers() throws Exception {
   292         final long res = -0xabcdef / -0x123;
   293         assertExec("Division Small Negative Numbers",
   294             Numbers.class, "divL__J_3B_3B",
   295             Double.valueOf(res),
   296             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x11 },
   297             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   298         );
   299     }
   300 
   301     @Test public void longDivideSmallMixedNumbers() throws Exception {
   302         final long res = 0xabcdef / -0x123;
   303         assertExec("Division Small Mixed Numbers",
   304             Numbers.class, "divL__J_3B_3B",
   305             Double.valueOf(res),
   306             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   307             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   308         );
   309     }
   310 
   311     @Test public void longDividePositiveNumbersOneDigitDenom()
   312             throws Exception {
   313         final long res = 0xabcdef0102ffffL / 0x654;
   314         assertExec("Division Positive Numbers One Digit Denom",
   315             Numbers.class, "divL__J_3B_3B",
   316             Double.valueOf(res),
   317             new byte[] { (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0x01, (byte)0x02, (byte)0xff, (byte)0xff },
   318             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   319         );
   320     }
   321 
   322     @Test public void longDivideNegativeNumbersOneDigitDenom()
   323             throws Exception {
   324         final long res = -0xabcdef0102ffffL / -0x654;
   325         assertExec("Division Negative Numbers One Digit Denom",
   326             Numbers.class, "divL__J_3B_3B",
   327             Double.valueOf(res),
   328             new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   329             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf9, (byte)0xac }
   330         );
   331     }
   332 
   333     @Test public void longDivideMixedNumbersOneDigitDenom()
   334             throws Exception {
   335         final long res = -0xabcdef0102ffffL / 0x654;
   336         assertExec("Division Mixed Numbers One Digit Denom",
   337             Numbers.class, "divL__J_3B_3B",
   338             Double.valueOf(res),
   339             new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   340             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   341         );
   342     }
   343 
   344     @Test public void longDividePositiveNumbersMultiDigitDenom()
   345             throws Exception {
   346         final long res = 0x7ffefc003322aabbL / 0x89ab1000L;
   347         assertExec("Division Positive Numbers Multi Digit Denom",
   348             Numbers.class, "divL__J_3B_3B",
   349             Double.valueOf(res),
   350             new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   351             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x89, (byte)0xab, (byte)0x10, (byte)0x00 }
   352         );
   353     }
   354 
   355     @Test public void longDivideNegativeNumbersMultiDigitDenom()
   356             throws Exception {
   357         final long res = -0x7ffefc003322aabbL / -0x123489ab1001L;
   358         assertExec("Division Negative Numbers Multi Digit Denom",
   359             Numbers.class, "divL__J_3B_3B",
   360             Double.valueOf(res),
   361             new byte[] { (byte)0x80, (byte)0x01, (byte)0x03, (byte)0xff, (byte)0xcc, (byte)0xdd, (byte)0x55, (byte)0x45 },
   362             new byte[] { (byte)0xff, (byte)0xff, (byte)0xed, (byte)0xcb, (byte)0x76, (byte)0x54, (byte)0xef, (byte)0xff }
   363         );
   364     }
   365 
   366     @Test public void longDivideMixedNumbersMultiDigitDenom()
   367             throws Exception {
   368         final long res = 0x7ffefc003322aabbL / -0x38f49b0b7574e36L;
   369         assertExec("Division Mixed Numbers Multi Digit Denom",
   370             Numbers.class, "divL__J_3B_3B",
   371             Double.valueOf(res),
   372             new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   373             new byte[] { (byte)0xfc, (byte)0x70, (byte)0xb6, (byte)0x4f, (byte)0x48, (byte)0xa8, (byte)0xb1, (byte)0xca }
   374         );
   375     }
   376 
   377     @Test public void longDivideWithOverflow() throws Exception {
   378         final long res = 0x8000fffe0000L / 0x8000ffffL;
   379         assertExec("Division With Overflow",
   380             Numbers.class, "divL__J_3B_3B",
   381             Double.valueOf(res),
   382             new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 },
   383             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xff }
   384         );
   385     }
   386 
   387     @Test public void longDivideWithCorrection() throws Exception {
   388         final long res = 0x7fff800000000000L / 0x800000000001L;
   389         assertExec("Division With Correction",
   390             Numbers.class, "divL__J_3B_3B",
   391             Double.valueOf(res),
   392             new byte[] { (byte)0x7f, (byte)0xff, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   393             new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 }
   394         );
   395     }
   396 
   397     @Test public void longModuloSmallPositiveNumbers() throws Exception {
   398         final long res = 0xabcdef % 0x123;
   399         assertExec("Modulo Small Positive Numbers",
   400             Numbers.class, "modL__J_3B_3B",
   401             Double.valueOf(res),
   402             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   403             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x23 }
   404         );
   405     }
   406 
   407     @Test public void longModuloSmallNegativeNumbers() throws Exception {
   408         final long res = -0xabcdef % -0x123;
   409         assertExec("Modulo Small Negative Numbers",
   410             Numbers.class, "modL__J_3B_3B",
   411             Double.valueOf(res),
   412             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x11 },
   413             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   414         );
   415     }
   416 
   417     @Test public void longModuloSmallMixedNumbers() throws Exception {
   418         final long res = 0xabcdef % -0x123;
   419         assertExec("Modulo Small Mixed Numbers",
   420             Numbers.class, "modL__J_3B_3B",
   421             Double.valueOf(res),
   422             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
   423             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
   424         );
   425     }
   426 
   427     @Test public void longModuloPositiveNumbersOneDigitDenom()
   428             throws Exception {
   429         final long res = 0xabcdef0102ffffL % 0x654;
   430         assertExec("Modulo Positive Numbers One Digit Denom",
   431             Numbers.class, "modL__J_3B_3B",
   432             Double.valueOf(res),
   433             new byte[] { (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0x01, (byte)0x02, (byte)0xff, (byte)0xff },
   434             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   435         );
   436     }
   437 
   438     @Test public void longModuloNegativeNumbersOneDigitDenom()
   439             throws Exception {
   440         final long res = -0xabcdef0102ffffL % -0x654;
   441         assertExec("Modulo Negative Numbers One Digit Denom",
   442             Numbers.class, "modL__J_3B_3B",
   443             Double.valueOf(res),
   444             new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   445             new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf9, (byte)0xac }
   446         );
   447     }
   448 
   449     @Test public void longModuloMixedNumbersOneDigitDenom()
   450             throws Exception {
   451         final long res = -0xabcdef0102ffffL % 0x654;
   452         assertExec("Modulo Mixed Numbers One Digit Denom",
   453             Numbers.class, "modL__J_3B_3B",
   454             Double.valueOf(res),
   455             new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
   456             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
   457         );
   458     }
   459 
   460     @Test public void longModuloPositiveNumbersMultiDigitDenom()
   461             throws Exception {
   462         final long res = 0x7ffefc003322aabbL % 0x89ab1000L;
   463         assertExec("Modulo Positive Numbers Multi Digit Denom",
   464             Numbers.class, "modL__J_3B_3B",
   465             Double.valueOf(res),
   466             new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   467             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x89, (byte)0xab, (byte)0x10, (byte)0x00 }
   468         );
   469     }
   470 
   471     @Test public void longModuloNegativeNumbersMultiDigitDenom()
   472             throws Exception {
   473         final long res = -0x7ffefc003322aabbL % -0x123489ab1001L;
   474         assertExec("Modulo Negative Numbers Multi Digit Denom",
   475             Numbers.class, "modL__J_3B_3B",
   476             Double.valueOf(res),
   477             new byte[] { (byte)0x80, (byte)0x01, (byte)0x03, (byte)0xff, (byte)0xcc, (byte)0xdd, (byte)0x55, (byte)0x45 },
   478             new byte[] { (byte)0xff, (byte)0xff, (byte)0xed, (byte)0xcb, (byte)0x76, (byte)0x54, (byte)0xef, (byte)0xff }
   479         );
   480     }
   481 
   482     @Test public void longModuloMixedNumbersMultiDigitDenom()
   483             throws Exception {
   484         final long res = 0x7ffefc003322aabbL % -0x38f49b0b7574e36L;
   485         assertExec("Modulo Mixed Numbers Multi Digit Denom",
   486             Numbers.class, "modL__J_3B_3B",
   487             Double.valueOf(res),
   488             new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
   489             new byte[] { (byte)0xfc, (byte)0x70, (byte)0xb6, (byte)0x4f, (byte)0x48, (byte)0xa8, (byte)0xb1, (byte)0xca }
   490         );
   491     }
   492 
   493     @Test public void longModuloWithOverflow() throws Exception {
   494         final long res = 0x8000fffe0000L % 0x8000ffffL;
   495         assertExec("Modulo With Overflow",
   496             Numbers.class, "modL__J_3B_3B",
   497             Double.valueOf(res),
   498             new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 },
   499             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xff }
   500         );
   501     }
   502 
   503     @Test public void longModuloWithCorrection() throws Exception {
   504         final long res = 0x7fff800000000000L % 0x800000000001L;
   505         assertExec("Modulo With Correction",
   506             Numbers.class, "modL__J_3B_3B",
   507             Double.valueOf(res),
   508             new byte[] { (byte)0x7f, (byte)0xff, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
   509             new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 }
   510         );
   511     }
   512 
   513     @Test public void longShiftL1() throws Exception {
   514         final long res = 0x00fa37d7763e0ca1l << 5;
   515         assertExec("Long << 5",
   516             Numbers.class, "shlL__J_3BI", 
   517             Double.valueOf(res),
   518                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   519                 5);
   520     }
   521     
   522     @Test public void longShiftL2() throws Exception {
   523         final long res = 0x00fa37d7763e0ca1l << 32;
   524         assertExec("Long << 32",
   525             Numbers.class, "shlL__J_3BI", 
   526             Double.valueOf(res),
   527                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   528                 32);
   529     }
   530     
   531     @Test public void longShiftL3() throws Exception {
   532         final long res = 0x00fa37d7763e0ca1l << 45;
   533         assertExec("Long << 45",
   534             Numbers.class, "shlL__J_3BI", 
   535             Double.valueOf(res),
   536                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   537                 45);
   538     }
   539     
   540     @Test public void longShiftR1() throws Exception {
   541         final long res = 0x00fa37d7763e0ca1l >> 5;
   542         assertExec("Long >> 5",
   543             Numbers.class, "shrL__J_3BI", 
   544             Double.valueOf(res),
   545                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   546                 5);
   547     }
   548     
   549     @Test public void longShiftR2() throws Exception {
   550         final long res = 0x00fa37d7763e0ca1l >> 32;
   551         assertExec("Long >> 32",
   552             Numbers.class, "shrL__J_3BI", 
   553             Double.valueOf(res),
   554                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   555                 32);
   556     }
   557     
   558     @Test public void longShiftR3() throws Exception {
   559         final long res = 0x00fa37d7763e0ca1l >> 45;
   560         assertExec("Long >> 45",
   561             Numbers.class, "shrL__J_3BI", 
   562             Double.valueOf(res),
   563                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   564                 45);
   565     }
   566     
   567     @Test public void longUShiftR1() throws Exception {
   568         final long res = 0x00fa37d7763e0ca1l >>> 5;
   569         assertExec("Long >>> 5",
   570             Numbers.class, "ushrL__J_3BI", 
   571             Double.valueOf(res),
   572                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   573                 5);
   574     }
   575     
   576     @Test public void longUShiftR2() throws Exception {
   577         final long res = 0x00fa37d7763e0ca1l >>> 45;
   578         assertExec("Long >>> 45",
   579             Numbers.class, "ushrL__J_3BI", 
   580             Double.valueOf(res),
   581                 new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   582                 45);
   583     }
   584     
   585     @Test public void longUShiftR3() throws Exception {
   586         final long res = 0xf0fa37d7763e0ca1l >>> 5;
   587         assertExec("Long >>> 5",
   588             Numbers.class, "ushrL__J_3BI", 
   589             Double.valueOf(res),
   590                 new byte[] { (byte)0xf0, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   591                 5);
   592     }
   593     
   594     @Test public void longUShiftR4() throws Exception {
   595         final long res = 0xf0fa37d7763e0ca1l >>> 45;
   596         assertExec("Long >>> 45",
   597             Numbers.class, "ushrL__J_3BI", 
   598             Double.valueOf(res),
   599                 new byte[] { (byte)0xf0, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   600                 45);
   601     }
   602     
   603     @Test public void longAnd() throws Exception {
   604         final long res = 0x00fa37d7763e0ca1l & 0xa7b3432fff00123el;
   605         assertExec("LOng binary AND",
   606             Numbers.class, "andL__J_3B_3B", 
   607             Double.valueOf(res),
   608             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   609             new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   610         );
   611     }
   612     
   613     @Test public void longOr() throws Exception {
   614         final long res = 0x00fa37d7763e0ca1l | 0xa7b3432fff00123el;
   615         assertExec("Long binary OR",
   616             Numbers.class, "orL__J_3B_3B", 
   617             Double.valueOf(res),
   618             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   619             new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   620         );
   621     }
   622     
   623     @Test public void longXor1() throws Exception {
   624         final long res = 0x00fa37d7763e0ca1l ^ 0xa7b3432fff00123el;
   625         assertExec("Long binary XOR",
   626             Numbers.class, "xorL__J_3B_3B", 
   627             Double.valueOf(res),
   628             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   629             new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   630         );
   631     }
   632     
   633     @Test public void longXor2() throws Exception {
   634         final long res = 0x00fa37d7763e0ca1l ^ 0x00000000ff00123el;
   635         assertExec("Long binary XOR",
   636             Numbers.class, "xorL__J_3B_3B", 
   637             Double.valueOf(res),
   638             new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   639             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   640         );
   641     }
   642     
   643     @Test public void longXor3() throws Exception {
   644         final long res = 0x00000000763e0ca1l ^ 0x00000000ff00123el;
   645         assertExec("Long binary XOR",
   646             Numbers.class, "xorL__J_3B_3B", 
   647             Double.valueOf(res),
   648             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
   649             new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
   650         );
   651     }
   652     
   653     private static CharSequence codeSeq;
   654     private static Invocable code;
   655 
   656     @BeforeClass
   657     public void compileTheCode() throws Exception {
   658         if (codeSeq == null) {
   659             StringBuilder sb = new StringBuilder();
   660             code = StaticMethodTest.compileClass(sb, "org/apidesign/vm4brwsr/Numbers");
   661             codeSeq = sb;
   662         }
   663     }
   664 
   665     private static void assertExec(
   666         String msg, Class<?> clazz, String method, Object expRes, Object... args) throws Exception
   667     {
   668         Object ret = TestUtils.execCode(code, codeSeq, msg, clazz, method, expRes, args);
   669         if (ret == null) {
   670             return;
   671         }
   672         if (expRes instanceof Double && ret instanceof Double) {
   673             double expD = ((Double)expRes).doubleValue();
   674             double retD = ((Double)ret).doubleValue();
   675             assertEquals(retD, expD, 0.000004, msg + " "
   676                     + StaticMethodTest.dumpJS(codeSeq));
   677             return;
   678         }
   679         assertEquals(ret, expRes, msg + " " + StaticMethodTest.dumpJS(codeSeq));
   680     }
   681     
   682 }