1 /*
   2  * Copyright 2005 Sun Microsystems, Inc.  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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 6274390
  27  * @summary Verify {float, double}Value methods work with condensed representation
  28  */
  29 import java.math.*;
  30 
  31 public class FloatDoubleValueTests {
  32     private static final long two2the24 = 1L<<23;
  33     private static final long two2the53 = 1L<<52;
  34 
  35     // Largest long that fits exactly in a float
  36     private static final long maxFltLong = (long)(Integer.MAX_VALUE & ~(0xff));
  37 
  38     // Largest long that fits exactly in a double
  39     private static final long maxDblLong = Long.MAX_VALUE & ~(0x7ffL);
  40 
  41     static void testDoubleValue0(long i, BigDecimal bd) {
  42         if (bd.doubleValue() != i ||
  43             bd.longValue()   != i)
  44             throw new RuntimeException("Unexpected equality failure for " +
  45                                        i + "\t" + bd);
  46     }
  47 
  48     static void testFloatValue0(long i, BigDecimal bd) {
  49         if (bd.floatValue() != i ||
  50             bd.longValue()   != i)
  51             throw new RuntimeException("Unexpected equality failure for " +
  52                                        i + "\t" + bd);
  53     }
  54 
  55     static void checkFloat(BigDecimal bd, float f) {
  56         float fbd = bd.floatValue();
  57         if (f != fbd ) {
  58             String message = String.format("Bad conversion:"+
  59                                            "got %g (%a)\texpected %g (%a)",
  60                                            f, f, fbd, fbd);
  61             throw new RuntimeException(message);
  62         }
  63     }
  64 
  65     static void checkDouble(BigDecimal bd, double d) {
  66         double dbd = bd.doubleValue();
  67         if (d != dbd ) {
  68             String message = String.format("Bad conversion:"+
  69                                            "got %g (%a)\texpected %g (%a)",
  70                                            d, d, dbd, dbd);
  71             throw new RuntimeException(message);
  72         }
  73     }
  74 
  75     // Test integral values that will convert exactly to both float
  76     // and double.
  77     static void testFloatDoubleValue() {
  78         long longValues[] = {
  79             0,
  80             1,
  81             2,
  82 
  83             two2the24-1,
  84             two2the24,
  85             two2the24+1,
  86 
  87             maxFltLong-1,
  88             maxFltLong,
  89             maxFltLong+1,
  90         };
  91 
  92         for(long i : longValues) {
  93             BigDecimal bd1 = new BigDecimal(i);
  94             BigDecimal bd2 = new BigDecimal(-i);
  95 
  96             testDoubleValue0( i, bd1);
  97             testDoubleValue0(-i, bd2);
  98 
  99             testFloatValue0( i, bd1);
 100             testFloatValue0(-i, bd2);
 101         }
 102 
 103     }
 104 
 105     static void testDoubleValue() {
 106         long longValues[] = {
 107             Integer.MAX_VALUE-1,
 108             Integer.MAX_VALUE,
 109             (long)Integer.MAX_VALUE+1,
 110 
 111             two2the53-1,
 112             two2the53,
 113             two2the53+1,
 114 
 115             maxDblLong,
 116         };
 117 
 118         // Test integral values that will convert exactly to double
 119         // but not float.
 120         for(long i : longValues) {
 121             BigDecimal bd1 = new BigDecimal(i);
 122             BigDecimal bd2 = new BigDecimal(-i);
 123 
 124             testDoubleValue0( i, bd1);
 125             testDoubleValue0(-i, bd2);
 126 
 127             checkFloat(bd1, (float)i);
 128             checkFloat(bd2, -(float)i);
 129         }
 130 
 131         // Now check values that should not convert the same in double
 132         for(long i = maxDblLong; i < Long.MAX_VALUE; i++) {
 133             BigDecimal bd1 = new BigDecimal(i);
 134             BigDecimal bd2 = new BigDecimal(-i);
 135             checkDouble(bd1, (double)i);
 136             checkDouble(bd2, -(double)i);
 137 
 138             checkFloat(bd1, (float)i);
 139             checkFloat(bd2, -(float)i);
 140         }
 141 
 142         checkDouble(new BigDecimal(Long.MIN_VALUE), (double)Long.MIN_VALUE);
 143         checkDouble(new BigDecimal(Long.MAX_VALUE), (double)Long.MAX_VALUE);
 144     }
 145 
 146     static void testFloatValue() {
 147         // Now check values that should not convert the same in float
 148         for(long i = maxFltLong; i <= Integer.MAX_VALUE; i++) {
 149             BigDecimal bd1 = new BigDecimal(i);
 150             BigDecimal bd2 = new BigDecimal(-i);
 151             checkFloat(bd1, (float)i);
 152             checkFloat(bd2, -(float)i);
 153 
 154             testDoubleValue0( i, bd1);
 155             testDoubleValue0(-i, bd2);
 156         }
 157     }
 158 
 159     public static void main(String[] args) throws Exception {
 160         testFloatDoubleValue();
 161         testDoubleValue();
 162         testFloatValue();
 163     }
 164 }