@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;
  }
Beispiel #2
0
  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);
  }
Beispiel #4
0
 @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;
   }
 }
Beispiel #7
0
 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;
  }
Beispiel #12
0
 /*
  * 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;
 }
Beispiel #13
0
  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;
    }
  }
Beispiel #15
0
 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;
 }
Beispiel #16
0
  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;
  }