@Override protected <T> String internalValueToString( final T value, final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException { String result; if (value instanceof Long || value instanceof Integer || value instanceof Short || value instanceof Byte || value instanceof BigInteger) { result = value.toString(); final int digits = result.startsWith("-") ? result.length() - 1 : result.length(); if (precision != null && precision < digits) { throw new EdmPrimitiveTypeException( "The value '" + value + "' does not match the facets' constraints."); } } else if (value instanceof Double || value instanceof Float || value instanceof BigDecimal) { BigDecimal bigDecimalValue; try { bigDecimalValue = value instanceof Double ? BigDecimal.valueOf((Double) value) : value instanceof Float ? BigDecimal.valueOf((Float) value) : (BigDecimal) value; } catch (final NumberFormatException e) { throw new EdmPrimitiveTypeException("The value '" + value + "' is not valid.", e); } final int digits = bigDecimalValue.scale() >= 0 ? Math.max(bigDecimalValue.precision(), bigDecimalValue.scale()) : bigDecimalValue.precision() - bigDecimalValue.scale(); if ((precision == null || precision >= digits) && (bigDecimalValue.scale() <= (scale == null ? 0 : scale))) { result = bigDecimalValue.toPlainString(); } else { throw new EdmPrimitiveTypeException( "The value '" + value + "' does not match the facets' constraints."); } } else { throw new EdmPrimitiveTypeException( "The value type " + value.getClass() + " is not supported."); } return result; }
private static BigInteger getNearby(BigInteger significand, int binExp, int offset) { int nExtraBits = 1; int nDec = (int) Math.round(3.0 + (64 + nExtraBits) * Math.log10(2.0)); BigInteger newFrac = significand.shiftLeft(nExtraBits).add(BigInteger.valueOf(offset)); int gg = 64 + nExtraBits - binExp - 1; BigDecimal bd = new BigDecimal(newFrac); if (gg > 0) { bd = bd.divide(new BigDecimal(BigInteger.ONE.shiftLeft(gg))); } else { BigInteger frac = newFrac; while (frac.bitLength() + binExp < 180) { frac = frac.multiply(BigInteger.TEN); } int binaryExp = binExp - newFrac.bitLength() + frac.bitLength(); bd = new BigDecimal(frac.shiftRight(frac.bitLength() - binaryExp - 1)); } int excessPrecision = bd.precision() - nDec; if (excessPrecision > 0) { bd = bd.setScale(bd.scale() - excessPrecision, BigDecimal.ROUND_HALF_UP); } return bd.unscaledValue(); }
/** * @param minValue * @param maxValue * @param scale * @param isForFunctionalBin Functional bins should always be non-sci notation. * @return */ public static DecimalFormat getFormat( BigDecimal minValue, BigDecimal maxValue, int scale, boolean isForFunctionalBin) { // Find number of digits left of decimal BigDecimal maxAbs = minValue.abs(); maxAbs = maxAbs.max(maxValue.abs()); int digitsLeftOfDecimal = Math.abs(maxAbs.precision() - maxAbs.scale()); boolean useSciNotation = (digitsLeftOfDecimal > 4 || scale > 4) && !isForFunctionalBin; String formatStr = null; if (useSciNotation) { if (scale > 0) { // Sig figs beyond the decimal (decimal fraction number) formatStr = "0." + StringUtils.repeat("0", scale) + "E0"; } else { // will contain no decimal number formatStr = "##0.##E0"; } } else { if (scale > 0) { // Sig figs beyond the decimal (decimal fraction number) formatStr = "0." + StringUtils.repeat("0", scale); } else { // will contain no decimal number formatStr = "0"; } } return new DecimalFormat(formatStr); }
@Override public int getDecimalPrecision() { BigDecimal d = getDecimal(); if (d != null) { return d.precision(); } return 0; }
public CalculatorToken(BigDecimal v, boolean approx) { this.value = v; this.isApprox = approx; if (approx) { this.minScale = v.scale(); this.minPrecision = v.precision(); } }
/** * Returns the scale (ie the BigDecimal concept of scale) of the most significant digit of the * value. * * <p>Examples: * * <ul> * <li>The scale of 1.49523 is 0 * <li>The scale of 0.149523 is 1 * <li>The scale of 14.9523 is -1 * <li>The scale of 0 is 0 * * @param value * @return */ public static int getScaleOfMostSignificantDigit(BigDecimal value) { if (value.compareTo(BigDecimal.ZERO) == 0) { // Some multi-decimal place forms of zero return a non-zero result // for the equation below, even when stripped. return 0; } else { return value.scale() - value.precision() + 1; } }
public static String getBaseDecimal(ExpandedDouble hd) { int gg = 64 - hd.getBinaryExponent() - 1; BigDecimal bd = new BigDecimal(hd.getSignificand()).divide(new BigDecimal(BigInteger.ONE.shiftLeft(gg))); int excessPrecision = bd.precision() - 23; if (excessPrecision > 0) { bd = bd.setScale(bd.scale() - excessPrecision, BigDecimal.ROUND_HALF_UP); } return bd.unscaledValue().toString(); }
public void setValue(JComponent component, String value) { NumberField numberField = (NumberField) component; if ("null".equals(value)) { numberField.setNumber(null); return; } BigDecimal number = getNumber(value); numberField.setMaximumFractionDigits(number.precision()); numberField.setNumber(number); }
public static Decimal38SparseHolder getDecimal38Holder(DrillBuf buf, String decimal) { Decimal38SparseHolder dch = new Decimal38SparseHolder(); BigDecimal bigDecimal = new BigDecimal(decimal); dch.scale = bigDecimal.scale(); dch.precision = bigDecimal.precision(); Decimal38SparseHolder.setSign(bigDecimal.signum() == -1, dch.start, dch.buffer); dch.start = 0; dch.buffer = buf.reallocIfNeeded(dch.maxPrecision * DecimalUtility.INTEGER_SIZE); DecimalUtility.getSparseFromBigDecimal( bigDecimal, dch.buffer, dch.start, dch.scale, dch.precision, dch.nDecimalDigits); return dch; }
protected static String getFriendlyFractionString(BigDecimal decimal) { // get the components of the number int wholeComponent = (int) decimal.doubleValue(); double fracComponent = decimal.doubleValue() - wholeComponent; String qtyString = ""; if (decimal.doubleValue() < 0.1) { qtyString = createFractionString(decimal); } else if (decimal.doubleValue() >= 0.1) { if (((fracComponent < 0.20)) || (fracComponent > 0.90)) { if (wholeComponent > 0) { qtyString = getSpecialSmallIntegerString(wholeComponent); } else { int exponent = decimal.precision() - decimal.scale() - 1; qtyString = decimal.round(new MathContext(exponent + 2)).toPlainString(); } } else if ((fracComponent >= 0.20) && (fracComponent < 0.30)) { if (wholeComponent > 0) { qtyString = wholeComponent + "-"; } qtyString += "1/4"; } else if ((fracComponent >= 0.30) && (fracComponent < 0.40)) { if (wholeComponent > 0) { qtyString = wholeComponent + "-"; } qtyString += "1/3"; } else if ((fracComponent >= 0.40) && (fracComponent < 0.60)) { if (wholeComponent > 0) { qtyString = wholeComponent + "-"; } qtyString += "1/2"; } else if ((fracComponent >= 0.60) && (fracComponent <= 0.70)) { if (wholeComponent > 0) { qtyString = wholeComponent + "-"; } qtyString += "2/3"; } else if ((fracComponent >= 0.70) && (fracComponent <= 0.90)) { if (wholeComponent > 0) { qtyString = wholeComponent + "-"; } qtyString += "3/4"; } } return qtyString; }
@Override public void comply(final E object) throws Exception { if (object == null) return; final int integerPartLength; final int fractionPartLength; try { final BigDecimal bigNum; if (object instanceof BigDecimal) bigNum = (BigDecimal) object; else bigNum = new BigDecimal(object.toString()).stripTrailingZeros(); integerPartLength = bigNum.precision() - bigNum.scale(); fractionPartLength = bigNum.scale() < 0 ? 0 : bigNum.scale(); } catch (Exception ex) { throw ex; } if (maxIntegerLength < integerPartLength || maxFractionLength < fractionPartLength) throw ex; }
/* * This little helper function converts a string to * a decimal, and, maybe, rounds it to the Volt default scale * using the given mode. If roundingEnabled is false, no * rounding is done. */ protected static final BigDecimal roundDecimalValue( String decimalValueString, boolean roundingEnabled, RoundingMode mode) { BigDecimal bd = new BigDecimal(decimalValueString); if (!roundingEnabled) { return bd; } int precision = bd.precision(); int scale = bd.scale(); int lostScale = scale - m_defaultScale; if (lostScale <= 0) { return bd; } int newPrecision = precision - lostScale; MathContext mc = new MathContext(newPrecision, mode); BigDecimal nbd = bd.round(mc); assertTrue(nbd.scale() <= m_defaultScale); if (nbd.scale() != m_defaultScale) { nbd = nbd.setScale(m_defaultScale); } assertEquals(getRoundingString("Decimal Scale setting failure"), m_defaultScale, nbd.scale()); return nbd; }
private static BigDecimal decimalPartitionKey(String value, DecimalType type, String name) { try { if (value.endsWith(BIG_DECIMAL_POSTFIX)) { value = value.substring(0, value.length() - BIG_DECIMAL_POSTFIX.length()); } BigDecimal decimal = new BigDecimal(value); decimal = decimal.setScale(type.getScale(), ROUND_UNNECESSARY); if (decimal.precision() > type.getPrecision()) { throw new PrestoException( HIVE_INVALID_PARTITION_VALUE, format( "Invalid partition value '%s' for %s partition key: %s", value, type.toString(), name)); } return decimal; } catch (NumberFormatException e) { throw new PrestoException( HIVE_INVALID_PARTITION_VALUE, format( "Invalid partition value '%s' for %s partition key: %s", value, type.toString(), name)); } }
/** * Rounds to the specified scale with constraints and rounding preferences. * * <p>Scale is basically decimal place. A scale of 1 means to round to one decimal place. 0 means * to round to the ones place. -2 rounds to the hundreds place. This is the same concept of scale * that BigDecimal uses. * * <p>First, rounding is done by three methods: HALF_EVEN, FLOOR and CEILING. Any round value that * goes outside the floor or ceiling value is eliminated. Then of the remaining values, preference * is given in the following order: * * <ul> * <li>The result using the least precision (ie the least number of digits) * <li>The result ending in a 5 * <li>The result that is even * <li>One of the remaining values * <li>If no values remain (all outside the bounds), the original value is returned. * * @param roundMe * @param floorValue Possible round values cannot be less than this number. * @param ceilingValue Possible round values cannot be greater than this nubmer. * @param finestScaleToRoundTo Finest (most toward positive) scale to round to. This is the * BigDecimal concept of scale - see getScaleOfMostSignificantDigit for discussion. * @return */ protected BigDecimal roundToNiceIfPossible( BigDecimal roundMe, BigDecimal floorValue, BigDecimal ceilingValue, int finestScaleToRoundTo) { roundMe = roundMe.stripTrailingZeros(); // required for calcs // Array of rounded values to try, rounding up & down at different scales ArrayList<BigDecimal> rounds = new ArrayList<BigDecimal>(6); // Try rounding to one digit left of the most significant digit (MSD) int startScale = getScaleOfMostSignificantDigit(roundMe) - 1; int endScale = finestScaleToRoundTo; // For the MSD if right of the decimal (.0000001), always start by try // to round to the ones place. if (startScale > 0) { startScale = 0; } if (finestScaleToRoundTo < startScale) { endScale = startScale; startScale = finestScaleToRoundTo; } // Create a list of rounded values, rounding from one digit left of the // most significant digit (i.e., 9 rounds to 10) down to the digit specified // by the scale of the CUV. Try up & down for each. for (int currentScale = startScale; currentScale <= endScale; currentScale++) { BigDecimal up = round(roundMe, currentScale, RoundingMode.CEILING); BigDecimal down = round(roundMe, currentScale, RoundingMode.FLOOR); if (up.compareTo(floorValue) >= 0 && up.compareTo(ceilingValue) <= 0) { rounds.add(up.stripTrailingZeros()); } if (down.compareTo(floorValue) >= 0 && down.compareTo(ceilingValue) <= 0) { rounds.add(down.stripTrailingZeros()); } } if (rounds.size() > 0) { // // Find the most desirable round BigDecimal leastPrecision = null; int numberOfOptionsWGreaterPrecision = 0; BigDecimal endsInFive = null; BigDecimal isEven = null; Iterator<BigDecimal> roundIt = rounds.iterator(); while (roundIt.hasNext()) { BigDecimal bd = roundIt.next(); if (bd.compareTo(BigDecimal.ZERO) == 0) { // Stop searching - a zero is always good return bd; } else if (leastPrecision == null) { leastPrecision = bd; } else if (bd.precision() < leastPrecision.precision()) { leastPrecision = bd; numberOfOptionsWGreaterPrecision++; } else if (leastPrecision.precision() < bd.precision()) { numberOfOptionsWGreaterPrecision++; } String intStr = bd.unscaledValue().toString(); String lastDigit = intStr.substring(intStr.length() - 1); if (lastDigit.equals("5")) { endsInFive = bd; } // Skip 0 b/c it will be less precision (handled above) if ("2468".indexOf(lastDigit) > 0) { isEven = bd; } } if (numberOfOptionsWGreaterPrecision > 0) { return leastPrecision; } else if (endsInFive != null) { return endsInFive; } else if (isEven != null) { return isEven; } else { return rounds.get(0); // Good enough } } else { // all rounded values were outside the constraints return roundMe; } }
public static byte[] toByteArray( String s, int radix, boolean fp, int size, boolean signed, boolean big_endian) throws Exception { byte[] bf = null; if (!fp) { bf = new BigInteger(s, radix).toByteArray(); } else if (size == 4) { int n = Float.floatToIntBits(Float.parseFloat(s)); bf = new byte[size]; for (int i = 0; i < size; i++) { bf[i] = (byte) ((n >> ((size - 1 - i) * 8)) & 0xff); } } else if (size == 8) { long n = Double.doubleToLongBits(Double.parseDouble(s)); bf = new byte[size]; for (int i = 0; i < size; i++) { bf[i] = (byte) ((n >> ((size - 1 - i) * 8)) & 0xff); } } else if (size == 2 || size == 10 || size == 16) { BigDecimal d = new BigDecimal(s); int n = 0; int bin_scale = 0; for (n = 0; n < 1000; n++) { d = d.stripTrailingZeros(); int scale = d.scale(); if (scale > 0) { int x = d.precision(); if (x > 36) { x -= 36; if (x > scale) x = scale; d = d.setScale(scale - x, RoundingMode.HALF_DOWN); continue; } } if (scale < 0) { d = d.divide(BigDecimal.valueOf(2).pow(-scale)); bin_scale += scale; } else if (scale > 0) { d = d.multiply(BigDecimal.valueOf(2).pow(scale)); bin_scale += scale; } else { break; } } BigInteger man = d.unscaledValue(); int cmp = man.compareTo(BigInteger.ZERO); bf = new byte[size]; if (cmp != 0) { boolean sign = cmp < 0; if (sign) man = man.negate(); int man_bits = man.bitLength(); int man_offs = 0; int exp = 0; for (; ; ) { if (size == 2) { exp = man_bits - bin_scale + 14; if (exp <= 0) { man_bits += 1 - exp; exp = 0; } if (exp > 0x1f) exp = 0x1f; man_offs = 5; } else { exp = man_bits - bin_scale + 16382; if (exp <= 0) { man_bits += 1 - exp; exp = 0; } else if (size == 10) { man_bits++; } if (exp > 0x7fff) exp = 0x7fff; man_offs = 15; } // Rounding int rb = man_offs + man_bits - size * 8 - 1; if (rb >= 0 && man.testBit(rb)) { man = man.add(BigInteger.ONE.shiftLeft(rb)); man_bits = man.bitLength(); } else { break; } } if (sign) bf[0] |= 0x80; for (int i = 1; i <= man_offs; i++) { if (((1 << (man_offs - i)) & exp) != 0) { bf[i / 8] |= (1 << (7 - i % 8)); } } for (int i = 0; i < man_bits; i++) { int j = man_offs + i; // bit pos in bf int k = man_bits - i - 1; // bit pos in man if (j / 8 >= bf.length) break; if (i == 0) { assert man.testBit(k) == (exp > 0 && size != 10); } else if (man.testBit(k)) { bf[j / 8] |= (1 << (7 - j % 8)); } } } } else { throw new Exception("Unsupported floating point format"); } byte[] rs = new byte[size]; if (signed && rs.length > bf.length && (bf[0] & 0x80) != 0) { // Sign extension for (int i = 0; i < rs.length; i++) rs[i] = (byte) 0xff; } for (int i = 0; i < bf.length; i++) { // i == 0 -> least significant byte byte b = bf[bf.length - i - 1]; int j = big_endian ? rs.length - i - 1 : i; if (j >= 0 && j < rs.length) rs[j] = b; } return rs; }
public static String toFPString(byte[] data, int offs, int size, boolean big_endian) { assert offs + size <= data.length; if (size == 12) { // padded 80-bit extended precision on IA32 size = 10; } byte[] arr = new byte[size]; if (big_endian) { System.arraycopy(data, offs, arr, 0, size); } else { for (int i = 0; i < size; i++) { arr[arr.length - i - 1] = data[offs + i]; } } boolean neg = (arr[0] & 0x80) != 0; arr[0] &= 0x7f; int precision = 0; int exponent = 0; boolean nan = false; switch (size) { case 2: precision = 3; exponent = (arr[0] & 0x7c) >> 2; nan = exponent == 0x1f; arr[0] &= 0x03; if (exponent == 0) exponent = 1; else if (!nan) arr[0] |= 0x04; exponent -= 10; // Significand exponent -= 15; // Exponent bias break; case 4: precision = 7; exponent = ((arr[0] & 0x7f) << 1) | ((arr[1] & 0x80) >> 7); nan = exponent == 0xff; arr[0] = 0; arr[1] &= 0x7f; if (exponent == 0) exponent = 1; else if (!nan) arr[1] |= 0x80; exponent -= 23; // Significand exponent -= 127; // Exponent bias break; case 8: precision = 16; exponent = ((arr[0] & 0x7f) << 4) | ((arr[1] & 0xf0) >> 4); nan = exponent == 0x7ff; arr[0] = 0; arr[1] &= 0x0f; if (exponent == 0) exponent = 1; else if (!nan) arr[1] |= 0x10; exponent -= 52; // Significand exponent -= 1023; // Exponent bias break; case 10: case 16: precision = 34; exponent = ((arr[0] & 0x7f) << 8) | (arr[1] & 0xff); nan = exponent == 0x7fff; arr[0] = arr[1] = 0; if (size == 10) { exponent -= 63; // Significand if (nan) arr[2] &= 0x7f; } else { if (exponent == 0) exponent = 1; else if (!nan) arr[1] = 1; exponent -= 112; // Significand } exponent -= 16383; // Exponent bias break; default: return "Unsupported floating point format"; } if (nan) { for (int i = 0; i < arr.length; i++) { if (arr[i] != 0) return neg ? "-NaN" : "+NaN"; } return neg ? "-Infinity" : "+Infinity"; } BigDecimal a = new BigDecimal(new BigInteger(arr), 0); if (a.signum() != 0 && exponent != 0) { BigDecimal p = new BigDecimal(BigInteger.valueOf(2), 0); if (exponent > 0) { a = a.multiply(p.pow(exponent)); } else { BigDecimal b = p.pow(-exponent); a = a.divide(b, b.precision(), RoundingMode.HALF_DOWN); } if (precision != 0 && a.precision() > precision) { int scale = a.scale() - a.precision() + precision; a = a.setScale(scale, RoundingMode.HALF_DOWN); } } String s = a.toString(); if (neg) s = "-" + s; return s; }