902 public BigDecimal(double val, MathContext mc) { |
902 public BigDecimal(double val, MathContext mc) { |
903 if (Double.isInfinite(val) || Double.isNaN(val)) |
903 if (Double.isInfinite(val) || Double.isNaN(val)) |
904 throw new NumberFormatException("Infinite or NaN"); |
904 throw new NumberFormatException("Infinite or NaN"); |
905 // Translate the double into sign, exponent and significand, according |
905 // Translate the double into sign, exponent and significand, according |
906 // to the formulae in JLS, Section 20.10.22. |
906 // to the formulae in JLS, Section 20.10.22. |
907 int sign = (val >= 0.0 ? 1 : -1); // Preserving sign of zero doesn't matter |
|
908 int exponent = Math.getExponent(val); |
|
909 long valBits = Double.doubleToLongBits(val); |
907 long valBits = Double.doubleToLongBits(val); |
910 long significand = (exponent == (Double.MIN_EXPONENT-1) |
908 int sign = ((valBits >> 63) == 0 ? 1 : -1); |
911 ? (valBits & ((1L << 52) - 1)) << 1 |
909 int exponent = (int) ((valBits >> 52) & 0x7ffL); |
912 : (valBits & ((1L << 52) - 1)) | (1L << 52)); |
910 long significand = (exponent == 0 |
|
911 ? (valBits & ((1L << 52) - 1)) << 1 |
|
912 : (valBits & ((1L << 52) - 1)) | (1L << 52)); |
|
913 exponent -= 1075; |
913 // At this point, val == sign * significand * 2**exponent. |
914 // At this point, val == sign * significand * 2**exponent. |
914 |
915 |
915 /* |
916 /* |
916 * Special case zero to supress nonterminating normalization and bogus |
917 * Special case zero to supress nonterminating normalization and bogus |
917 * scale calculation. |
918 * scale calculation. |
931 int scale = 0; |
932 int scale = 0; |
932 // Calculate intVal and scale |
933 // Calculate intVal and scale |
933 BigInteger intVal; |
934 BigInteger intVal; |
934 long compactVal = sign * significand; |
935 long compactVal = sign * significand; |
935 if (exponent == 0) { |
936 if (exponent == 0) { |
936 // If the exponent is zero, the significant fits in a long |
937 intVal = (compactVal == INFLATED) ? INFLATED_BIGINT : null; |
937 assert compactVal != INFLATED; |
|
938 intVal = null; |
|
939 } else { |
938 } else { |
940 if (exponent < 0) { |
939 if (exponent < 0) { |
941 intVal = BigInteger.valueOf(5).pow(-exponent).multiply(compactVal); |
940 intVal = BigInteger.valueOf(5).pow(-exponent).multiply(compactVal); |
942 scale = -exponent; |
941 scale = -exponent; |
943 } else { // (exponent > 0) |
942 } else { // (exponent > 0) |
4160 |
4159 |
4161 case ROUND_FLOOR: // Towards -infinity |
4160 case ROUND_FLOOR: // Towards -infinity |
4162 return qsign < 0; |
4161 return qsign < 0; |
4163 |
4162 |
4164 default: // Some kind of half-way rounding |
4163 default: // Some kind of half-way rounding |
4165 if (roundingMode == ROUND_HALF_DOWN || |
4164 assert roundingMode >= ROUND_HALF_UP && |
4166 cmpFracHalf < 0 ) // We're closer to higher digit |
4165 roundingMode <= ROUND_HALF_EVEN: "Unexpected rounding mode" + RoundingMode.valueOf(roundingMode); |
|
4166 |
|
4167 if (cmpFracHalf < 0 ) // We're closer to higher digit |
4167 return false; |
4168 return false; |
4168 else if (roundingMode == ROUND_HALF_UP || |
4169 else if (cmpFracHalf > 0 ) // We're closer to lower digit |
4169 cmpFracHalf > 0 ) // We're closer to lower digit |
|
4170 return true; |
4170 return true; |
4171 else |
4171 else { // half-way |
4172 // roundingMode == ROUND_HALF_EVEN, true iff quotient is odd |
4172 assert cmpFracHalf == 0; |
4173 return oddQuot; |
4173 |
|
4174 switch(roundingMode) { |
|
4175 case ROUND_HALF_DOWN: |
|
4176 return false; |
|
4177 |
|
4178 case ROUND_HALF_UP: |
|
4179 return true; |
|
4180 |
|
4181 case ROUND_HALF_EVEN: |
|
4182 return oddQuot; |
|
4183 |
|
4184 default: |
|
4185 throw new AssertionError("Unexpected rounding mode" + roundingMode); |
|
4186 } |
|
4187 } |
4174 } |
4188 } |
4175 } |
4189 } |
4176 |
4190 |
4177 /** |
4191 /** |
4178 * Tests if quotient has to be incremented according the roundingMode |
4192 * Tests if quotient has to be incremented according the roundingMode |