1 /*
   2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 // This file is available under and governed by the GNU General Public
  27 // License version 2 only, as published by the Free Software Foundation.
  28 // However, the following notice accompanied the original version of this
  29 // file:
  30 //
  31 // Copyright 2006-2008 the V8 project authors. All rights reserved.
  32 
  33 package jdk.nashorn.internal.runtime.doubleconv.test;
  34 
  35 import org.testng.annotations.Test;
  36 
  37 import java.lang.reflect.Constructor;
  38 import java.lang.reflect.Method;
  39 
  40 import static org.testng.Assert.assertEquals;
  41 import static org.testng.Assert.assertTrue;
  42 
  43 /**
  44  * DiyFp class tests
  45  *
  46  * @test
  47  * @modules jdk.scripting.nashorn/jdk.nashorn.internal.runtime.doubleconv:open
  48  * @run testng jdk.nashorn.internal.runtime.doubleconv.test.DiyFpTest
  49  */
  50 @SuppressWarnings("javadoc")
  51 public class DiyFpTest {
  52 
  53     static final Class<?> DiyFp;
  54     static final Constructor<?> ctor;
  55 
  56     static {
  57         try {
  58             DiyFp = Class.forName("jdk.nashorn.internal.runtime.doubleconv.DiyFp");
  59             ctor = DiyFp.getDeclaredConstructor(long.class, int.class);
  60             ctor.setAccessible(true);
  61         } catch (final Exception e) {
  62             throw new RuntimeException(e);
  63         }
  64     }
  65 
  66     private static Method method(final String name, final Class<?>... params) throws NoSuchMethodException {
  67         final Method m = DiyFp.getDeclaredMethod(name, params);
  68         m.setAccessible(true);
  69         return m;
  70     }
  71 
  72     @Test
  73     public void testSubtract() throws Exception {
  74         final Object diyFp1 = ctor.newInstance(3, 0);
  75         final Object diyFp2 = ctor.newInstance(1, 0);
  76         final Object diff = method("minus", DiyFp, DiyFp).invoke(null, diyFp1, diyFp2);;
  77         assertTrue(2l == (long) method("f").invoke(diff));
  78         assertTrue(0 == (int) method("e").invoke(diff));
  79         method("subtract", DiyFp).invoke(diyFp1, diyFp2);
  80         assertTrue(2l == (long) method("f").invoke(diyFp1));
  81         assertTrue(0 == (int) method("e").invoke(diyFp2));
  82     }
  83 
  84     @Test
  85     public void testMultiply() throws Exception {
  86         Object diyFp1, diyFp2, product;
  87 
  88         diyFp1 = ctor.newInstance(3, 0);
  89         diyFp2 = ctor.newInstance(2, 0);
  90         product = method("times", DiyFp, DiyFp).invoke(null, diyFp1, diyFp2);
  91         assertEquals(0l, (long) method("f").invoke(product));
  92         assertEquals(64, (int) method("e").invoke(product));
  93         method("multiply", DiyFp).invoke(diyFp1, diyFp2);
  94         assertEquals(0l, (long) method("f").invoke(diyFp1));
  95         assertEquals(64, (int) method("e").invoke(diyFp1));
  96 
  97         diyFp1 = ctor.newInstance(0x8000000000000000L, 11);
  98         diyFp2 = ctor.newInstance(2, 13);
  99         product = method("times", DiyFp, DiyFp).invoke(null, diyFp1, diyFp2);
 100         assertEquals(1l, (long) method("f").invoke(product));
 101         assertEquals(11 + 13 + 64, (int) method("e").invoke(product));
 102 
 103         // Test rounding.
 104         diyFp1 = ctor.newInstance(0x8000000000000001L, 11);
 105         diyFp2 = ctor.newInstance(1, 13);
 106         product = method("times", DiyFp, DiyFp).invoke(null, diyFp1, diyFp2);
 107         assertEquals(1l, (long) method("f").invoke(product));
 108         assertEquals(11 + 13 + 64, (int) method("e").invoke(product));
 109 
 110         diyFp1 = ctor.newInstance(0x7fffffffffffffffL, 11);
 111         diyFp2 = ctor.newInstance(1, 13);
 112         product = method("times", DiyFp, DiyFp).invoke(null, diyFp1, diyFp2);
 113         assertEquals(0l, (long) method("f").invoke(product));
 114         assertEquals(11 + 13 + 64, (int) method("e").invoke(product));
 115 
 116         // Big numbers.
 117         diyFp1 = ctor.newInstance(0xFFFFFFFFFFFFFFFFL, 11);
 118         diyFp2 = ctor.newInstance(0xFFFFFFFFFFFFFFFFL, 13);
 119         // 128bit result: 0xfffffffffffffffe0000000000000001
 120         product = method("times", DiyFp, DiyFp).invoke(null, diyFp1, diyFp2);
 121         assertEquals(0xFFFFFFFFFFFFFFFel, (long) method("f").invoke(product));
 122         assertEquals(11 + 13 + 64, (int) method("e").invoke(product));
 123     }
 124 }