Java Code Examples for java.math.BigDecimal#movePointRight()

The following examples show how to use java.math.BigDecimal#movePointRight() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TimestampTest.java    From ion-java with Apache License 2.0 6 votes vote down vote up
@Test
public void testForSqlTimestampZ()
{
    long millis = System.currentTimeMillis();
    java.sql.Timestamp now = new java.sql.Timestamp(millis);
    assertEquals(millis % 1000 * 1000000, now.getNanos());

    Timestamp ts = Timestamp.forSqlTimestampZ(now);
    assertEquals(now.getTime(), ts.getMillis());
    assertEquals(Timestamp.UTC_OFFSET, ts.getLocalOffset());

    BigDecimal frac = ts.getFractionalSecond();
    frac = frac.movePointRight(9); // Convert to nanos
    assertEquals("nanos", now.getNanos(), frac.intValue());

    BigDecimal second = BigDecimal.valueOf(ts.getSecond());
    frac = ts.getDecimalSecond().subtract(second);
    frac = frac.movePointRight(9); // Convert to nanos
    assertEquals("nanos", now.getNanos(), frac.intValue());

    now.setTime(0);
    ts = Timestamp.forSqlTimestampZ(now);
    assertEquals(0, ts.getMillis());
    assertEquals(Timestamp.UTC_OFFSET, ts.getLocalOffset());
    assertEquals(1970, ts.getYear());
}
 
Example 2
Source File: CommitId.java    From javers with Apache License 2.0 5 votes vote down vote up
public static CommitId valueOf(BigDecimal majorDotMinor) {
    Validate.argumentIsNotNull(majorDotMinor);

    long major = majorDotMinor.longValue();
    BigDecimal minorFractional = majorDotMinor.subtract(BigDecimal.valueOf(major));
    BigDecimal minor = minorFractional.movePointRight(2);

    return new CommitId(major, minor.setScale(0, RoundingMode.HALF_UP).intValue());
}
 
Example 3
Source File: PersistentFastMoneyMinorAmountAndCurrency.java    From jadira with Apache License 2.0 5 votes vote down vote up
@Override
protected Object[] toConvertedColumns(MonetaryAmount value) {

    BigDecimal minorVal = value.getNumber().numberValue(BigDecimal.class);
    minorVal = minorVal.movePointRight(value.getCurrency().getDefaultFractionDigits());

    return new Object[] { value.getCurrency(), minorVal.longValue() };
}
 
Example 4
Source File: CurrencyMapper.java    From catatumbo with Apache License 2.0 5 votes vote down vote up
@Override
public ValueBuilder<?, ?, ?> toDatastore(Object input) {
  if (input == null) {
    return NullValue.newBuilder();
  }
  try {
    BigDecimal n = (BigDecimal) input;
    n = n.movePointRight(fractionalDigits);
    return LongValue.newBuilder(n.longValueExact());
  } catch (Exception e) {
    throw new MappingException(e);
  }
}
 
Example 5
Source File: TwoFactorPreferenceFragment.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
private void onNewLimitsSelected(final String amount, final boolean isFiat) {
    final BigDecimal unscaled = new BigDecimal(amount);
    final BigDecimal scaled = unscaled.movePointRight(isFiat ? 2 : 8);
    final long limit = scaled.longValue();

    // Only requires 2FA if we have it setup and we are increasing the limit
    final boolean skipChoice = !mService.doesLimitChangeRequireTwoFactor(limit, isFiat);
    if (skipChoice) {
        setSpendingLimits(mService.makeLimitsData(limit, isFiat), null);
        return;
    }

    final MaterialDialog mTwoFactor = UI.popupTwoFactorChoice(getActivity(), mService, skipChoice, new CB.Runnable1T<String>() {
        public void run(final String method) {
            final View v = inflatePinDialog(method);
            final EditText codeText = UI.find(v, R.id.btchipPINValue);
            final JSONMap limitsData = mService.makeLimitsData(limit, isFiat);

            if (!method.equals("gauth"))
                mService.requestTwoFacCode(method, "change_tx_limits", limitsData.mData);

            UI.popup(getActivity(), "Enter TwoFactor Code")
              .customView(v, true)
              .onPositive(new MaterialDialog.SingleButtonCallback() {
                  @Override
                  public void onClick(final MaterialDialog dialog, final DialogAction which) {
                      final String code = UI.getText(codeText);
                      setSpendingLimits(limitsData, mService.make2FAData(method, code));
                  }
              }).build().show();
        }
    });
    if (mTwoFactor != null)
        mTwoFactor.show();
}
 
Example 6
Source File: PersistentMoneyMinorAmountAndCurrency.java    From jadira with Apache License 2.0 5 votes vote down vote up
@Override
protected Object[] toConvertedColumns(MonetaryAmount value) {

    BigDecimal minorVal = value.getNumber().numberValue(BigDecimal.class);
    minorVal = minorVal.movePointRight(value.getCurrency().getDefaultFractionDigits());

    return new Object[] { value.getCurrency(), minorVal.longValue() };
}
 
Example 7
Source File: DecimalUnitFormat.java    From tracecompass with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * @since 2.2
 */
@Override
public Number parseObject(String source, ParsePosition pos) {
    Number number = NumberFormat.getInstance().parse(source, pos);
    if (number == null) {
        return null;
    }
    // Try to match the unit, if no match, assume no unit and don't
    // update the position
    String remaining = source.substring(pos.getIndex());
    Matcher matcher = UNIT_PATTERN.matcher(remaining);
    Integer exponent = null;
    if (matcher.find()) {
        String unitString = matcher.group();
        String prefix = matcher.group(1);
        exponent = PREFIX_MAP.get(prefix);
        pos.setIndex(pos.getIndex() + unitString.length());
    }
    if (exponent != null && Double.isFinite(number.doubleValue())) {
        // Calculate the value with exponent
        BigDecimal bd = new BigDecimal(number.toString());
        bd = bd.movePointRight(exponent.intValue());
        if (bd.remainder(BigDecimal.ONE).equals(BigDecimal.ZERO) &&
                bd.abs().compareTo(new BigDecimal(Long.MAX_VALUE)) < 0) {
            return bd.longValue();
        }
        return bd.doubleValue();
    }
    return number;
}
 
Example 8
Source File: BsqValidator.java    From bisq with GNU Affero General Public License v3.0 5 votes vote down vote up
private ValidationResult validateIfNotFractionalBtcValue(String input) {
    BigDecimal bd = new BigDecimal(input);
    final BigDecimal satoshis = bd.movePointRight(2);
    if (satoshis.scale() > 0)
        return new ValidationResult(false, Res.get("validation.btc.fraction"));
    else
        return new ValidationResult(true);
}
 
Example 9
Source File: BtcValidator.java    From bisq with GNU Affero General Public License v3.0 5 votes vote down vote up
protected ValidationResult validateIfNotFractionalBtcValue(String input) {
    try {
        BigDecimal bd = new BigDecimal(input);
        final BigDecimal satoshis = bd.movePointRight(8);
        if (satoshis.scale() > 0)
            return new ValidationResult(false, Res.get("validation.btc.fraction"));
        else
            return new ValidationResult(true);
    } catch (Throwable t) {
        return new ValidationResult(false, Res.get("validation.invalidInput", t.getMessage()));
    }
}
 
Example 10
Source File: TestUtils.java    From sarl with Apache License 2.0 5 votes vote down vote up
/** Replies if two values are equals at epsilon.
 *
 * @param v1 the first value.
 * @param v2 the second value.
 * @param precision is the number of decimal digits to test.
 * @return <code>true</code> or <code>false</code>
 */
@Pure
public static boolean isEpsilonEquals(BigDecimal v1, BigDecimal v2, int precision) {
	final BigDecimal ma = v1.movePointRight(precision);
	final BigDecimal mb = v2.movePointRight(precision);
	BigDecimal aa = ma.setScale(0, BigDecimal.ROUND_HALF_UP);
	BigDecimal bb = mb.setScale(0, BigDecimal.ROUND_HALF_UP);
	if (aa.compareTo(bb) == 0) {
		return true;
	}
	aa = ma.setScale(0, BigDecimal.ROUND_DOWN);
	bb = mb.setScale(0, BigDecimal.ROUND_DOWN);
	return aa.compareTo(bb) == 0;
}
 
Example 11
Source File: BtcAutoFormat.java    From green_android with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Calculate the appropriate denomination for the given Bitcoin monetary value.  This
 * method takes a BigInteger representing a quantity of satoshis, and returns the
 * number of places that value's decimal point is to be moved when formatting said value
 * in order that the resulting number represents the correct quantity of denominational
 * units.
 *
 * <p>As a side-effect, this sets the units indicators of the underlying NumberFormat object.
 * Only invoke this from a synchronized method, and be sure to put the DecimalFormatSymbols
 * back to its proper state, otherwise immutability, equals() and hashCode() fail.
 */
@Override
protected int scale(BigInteger satoshis, int fractionPlaces) {
    /* The algorithm is as follows.  TODO: is there a way to optimize step 4?
       1. Can we use coin denomination w/ no rounding?  If yes, do it.
       2. Else, can we use millicoin denomination w/ no rounding? If yes, do it.
       3. Else, can we use micro denomination w/ no rounding?  If yes, do it.
       4. Otherwise we must round:
         (a) round to nearest coin + decimals
         (b) round to nearest millicoin + decimals
         (c) round to nearest microcoin + decimals
         Subtract each of (a), (b) and (c) from the true value, and choose the
         denomination that gives smallest absolute difference.  It case of tie, use the
         smaller denomination.
    */
    int places;
    int coinOffset = Math.max(SMALLEST_UNIT_EXPONENT - fractionPlaces, 0);
    BigDecimal inCoins = new BigDecimal(satoshis).movePointLeft(coinOffset);
    if (inCoins.remainder(ONE).compareTo(ZERO) == 0) {
        places = COIN_SCALE;
    } else {
        BigDecimal inMillis = inCoins.movePointRight(MILLICOIN_SCALE);
        if (inMillis.remainder(ONE).compareTo(ZERO) == 0) {
            places = MILLICOIN_SCALE;
        } else {
            BigDecimal inMicros = inCoins.movePointRight(MICROCOIN_SCALE);
            if (inMicros.remainder(ONE).compareTo(ZERO) == 0) {
                places = MICROCOIN_SCALE;
            } else {
                // no way to avoid rounding: so what denomination gives smallest error?
                BigDecimal a = inCoins.subtract(inCoins.setScale(0, HALF_UP)).
                               movePointRight(coinOffset).abs();
                BigDecimal b = inMillis.subtract(inMillis.setScale(0, HALF_UP)).
                               movePointRight(coinOffset - MILLICOIN_SCALE).abs();
                BigDecimal c = inMicros.subtract(inMicros.setScale(0, HALF_UP)).
                               movePointRight(coinOffset - MICROCOIN_SCALE).abs();
                if (a.compareTo(b) < 0)
                    if (a.compareTo(c) < 0) places = COIN_SCALE;
                    else places = MICROCOIN_SCALE;
                else if (b.compareTo(c) < 0) places = MILLICOIN_SCALE;
                else places = MICROCOIN_SCALE;
            }
        }
    }
    prefixUnitsIndicator(numberFormat, places);
    return places;
}
 
Example 12
Source File: BigDecimalUtil.java    From objectlabkit with Apache License 2.0 4 votes vote down vote up
/**
 * Safe shift (check for null), shift RIGHT if shift&gt;0.
 */
public static BigDecimal movePoint(final BigDecimal v1, final int shift) {
    return v1 == null ? null : v1.movePointRight(shift);
}
 
Example 13
Source File: NumericFormat.java    From CloverETL-Engine with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * @param source
 * @param parsePosition
 * @return
 */
public BigDecimal parse(CharSequence source){
	boolean exponentForm = false;
	char decimalSeparator = dFormat.getDecimalFormatSymbols().getDecimalSeparator();
	boolean dSeparator = false;
	char groupingSeparator = dFormat.getDecimalFormatSymbols().getGroupingSeparator();
	String negativePrefix = dFormat.getNegativePrefix();
	String positivePrefix = dFormat.getPositivePrefix();
	int counter = 0;
	int length=source.length();
	char[] result = new char[length];
	int start = 0;
	try {
		if (negativePrefix.contentEquals(source.subSequence(0, negativePrefix.length()))) {
			result[counter++]='-';
			start = negativePrefix.length();			
		}else if (positivePrefix.contentEquals(source.subSequence(0, positivePrefix.length()))) {
			start = positivePrefix.length();
		}
	} catch (IndexOutOfBoundsException e) {	// not enough space for prefix
		// ignore
	}
	char[] chars;
	if (source instanceof CharBuffer && ((CharBuffer)source).hasArray()) {	// optimization
		chars = ((CharBuffer)source).array();
		start += ((CharBuffer)source).arrayOffset() + ((CharBuffer)source).position();
	} else {
		chars = new char[length];
		for (int idx = 0; idx < length; idx++) {
			chars[idx] = source.charAt(idx);
		}
		start = 0;
	}
	int end = start + length;
	int exponentPart=0;
	for (int j=start;j<end;j++){
		if (Character.isDigit(chars[j])){
			result[counter++]=chars[j];
		}else if (chars[j]==decimalSeparator){
			if (!dSeparator){//there was not decimal separator before
				result[counter++]='.';
				dSeparator = true;
			}else{//second decimal separator found
				throw new NumberFormatException("Cannot interpret \"" + source +"\" as a number. " +
						"Two decimal separators found.");
			}
		}else if (chars[j]==groupingSeparator && !dSeparator){//grouping separator is after decimal separator, rest of string is ignored
			continue;
		}else if (chars[j]==EXPONENT_SYMBOL[0] || chars[j]==EXPONENT_SYMBOL[1]){
			exponentForm = true;
			exponentPart = getExponentPart(chars,counter+1);
			break;
		}else{//unknown char or grouping separator is after decimal separator
			throw new NumberFormatException("Cannot interpret \"" + source +"\" as a number.");
		}
	}
	BigDecimal bigDecimal = new BigDecimal(String.copyValueOf(result,0,counter));
	if (exponentForm){
		return bigDecimal.movePointRight(exponentPart);
	}else{
		return bigDecimal;
	}
}
 
Example 14
Source File: NumericFormat.java    From CloverETL-Engine with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
    * @return BigDecimal
    * @deprecated
    */
@Override
public Number parse(String source, ParsePosition parsePosition){
	boolean exponentForm = false;
	char decimalSeparator = dFormat.getDecimalFormatSymbols().getDecimalSeparator();
	boolean dSeparator = false;
	char groupingSeparator = dFormat.getDecimalFormatSymbols().getGroupingSeparator();
	String negativePrefix = dFormat.getNegativePrefix();
	String positivePrefix = dFormat.getPositivePrefix();
	int start=0;
	int counter = 0;
	int length=source.length();
	char[]	chars=source.toCharArray();
	char[] result = new char[length];
	if (source.startsWith(negativePrefix)){
		result[counter++]='-';
		start = negativePrefix.length();
	}else if (source.startsWith(positivePrefix)){
		start = positivePrefix.length();
	}
	int exponentPart=0;
	for (int j=start;j<length;j++){
		if (Character.isDigit(chars[j])){
			result[counter++]=chars[j];
		}else if (chars[j]==decimalSeparator){
			if (!dSeparator){//there was not decimal separator before
				result[counter++]='.';
				dSeparator = true;
			}else{//second decimal separator found
				throw new NumberFormatException("Cannot interpret \"" + source +"\" as a number. " +
						"Two decimal separators found.");
			}
		}else if (chars[j]==groupingSeparator && !dSeparator){//grouping separator is after decimal separator, rest of string is ignored
			continue;
		}else if (chars[j]==EXPONENT_SYMBOL[0] || chars[j]==EXPONENT_SYMBOL[1]){
			exponentForm = true;
			exponentPart = getExponentPart(chars,counter+1);
			break;
		}else{//unknown char or grouping separator is after decimal separator 
			throw new NumberFormatException("Cannot interpret \"" + source +"\" as a number.");
		}
	}
	try {
		BigDecimal bigDecimal = new BigDecimal(String.copyValueOf(result,0,counter));
		parsePosition.setIndex(chars.length);
		if (exponentForm){
			return bigDecimal.movePointRight(exponentPart);
		}else{
			return bigDecimal;
		}
	}catch(NumberFormatException e){
		return null;
	}
}
 
Example 15
Source File: OrderedBytes.java    From hbase with Apache License 2.0 4 votes vote down vote up
/**
 * Encode the large magnitude floating point number {@code val} using
 * the key encoding. The caller guarantees that {@code val} will be
 * finite and abs(val) >= 1.0.
 * <p>
 * A floating point value is encoded as an integer exponent {@code E}
 * and a mantissa {@code M}. The original value is equal to
 * {@code (M * 100^E)}. {@code E} is set to the smallest value
 * possible without making {@code M} greater than or equal to 1.0.
 * </p>
 * <p>
 * Each centimal digit of the mantissa is stored in a byte. If the value of
 * the centimal digit is {@code X} (hence {@code X>=0} and
 * {@code X<=99}) then the byte value will be {@code 2*X+1} for
 * every byte of the mantissa, except for the last byte which will be
 * {@code 2*X+0}. The mantissa must be the minimum number of bytes
 * necessary to represent the value; trailing {@code X==0} digits are
 * omitted. This means that the mantissa will never contain a byte with the
 * value {@code 0x00}.
 * </p>
 * <p>
 * If {@code E > 10}, then this routine writes of {@code E} as a
 * varint followed by the mantissa as described above. Otherwise, if
 * {@code E <= 10}, this routine only writes the mantissa and leaves
 * the {@code E} value to be encoded as part of the opening byte of the
 * field by the calling function.
 *
 * <pre>
 *   Encoding:  M       (if E<=10)
 *              E M     (if E>10)
 * </pre>
 * </p>
 * @param dst The destination to which encoded digits are written.
 * @param val The value to encode.
 * @return the number of bytes written.
 */
private static int encodeNumericLarge(PositionedByteRange dst, BigDecimal val) {
  // TODO: this can be done faster
  BigDecimal abs = val.abs();
  byte[] a = dst.getBytes();
  boolean isNeg = val.signum() == -1;
  final int start = dst.getPosition(), offset = dst.getOffset();
  int e = 0, d, startM;

  if (isNeg) { /* Large negative number: 0x08, ~E, ~M */
    dst.put(NEG_LARGE);
  } else { /* Large positive number: 0x22, E, M */
    dst.put(POS_LARGE);
  }

  // normalize abs(val) to determine E
  while (abs.compareTo(E32) >= 0 && e <= 350) { abs = abs.movePointLeft(32); e +=16; }
  while (abs.compareTo(E8) >= 0 && e <= 350) { abs = abs.movePointLeft(8); e+= 4; }
  while (abs.compareTo(BigDecimal.ONE) >= 0 && e <= 350) { abs = abs.movePointLeft(2); e++; }

  // encode appropriate header byte and/or E value.
  if (e > 10) { /* large number, write out {~,}E */
    putVaruint64(dst, e, isNeg);
  } else {
    if (isNeg) { /* Medium negative number: 0x13-E, ~M */
      dst.put(start, (byte) (NEG_MED_MAX - e));
    } else { /* Medium positive number: 0x17+E, M */
      dst.put(start, (byte) (POS_MED_MIN + e));
    }
  }

  // encode M by peeling off centimal digits, encoding x as 2x+1
  startM = dst.getPosition();
  // TODO: 18 is an arbitrary encoding limit. Reevaluate once we have a better handling of
  // numeric scale.
  for (int i = 0; i < 18 && abs.compareTo(BigDecimal.ZERO) != 0; i++) {
    abs = abs.movePointRight(2);
    d = abs.intValue();
    dst.put((byte) (2 * d + 1));
    abs = abs.subtract(BigDecimal.valueOf(d));
  }
  // terminal digit should be 2x
  a[offset + dst.getPosition() - 1] = (byte) (a[offset + dst.getPosition() - 1] & 0xfe);
  if (isNeg) {
    // negative values encoded as ~M
    DESCENDING.apply(a, offset + startM, dst.getPosition() - startM);
  }
  return dst.getPosition() - start;
}
 
Example 16
Source File: BtcAutoFormat.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Calculate the appropriate denomination for the given Bitcoin monetary value.  This
 * method takes a BigInteger representing a quantity of satoshis, and returns the
 * number of places that value's decimal point is to be moved when formatting said value
 * in order that the resulting number represents the correct quantity of denominational
 * units.
 *
 * <p>As a side-effect, this sets the units indicators of the underlying NumberFormat object.
 * Only invoke this from a synchronized method, and be sure to put the DecimalFormatSymbols
 * back to its proper state, otherwise immutability, equals() and hashCode() fail.
 */
@Override
protected int scale(BigInteger satoshis, int fractionPlaces) {
    /* The algorithm is as follows.  TODO: is there a way to optimize step 4?
       1. Can we use coin denomination w/ no rounding?  If yes, do it.
       2. Else, can we use millicoin denomination w/ no rounding? If yes, do it.
       3. Else, can we use micro denomination w/ no rounding?  If yes, do it.
       4. Otherwise we must round:
         (a) round to nearest coin + decimals
         (b) round to nearest millicoin + decimals
         (c) round to nearest microcoin + decimals
         Subtract each of (a), (b) and (c) from the true value, and choose the
         denomination that gives smallest absolute difference.  It case of tie, use the
         smaller denomination.
    */
    int places;
    int coinOffset = Math.max(SMALLEST_UNIT_EXPONENT - fractionPlaces, 0);
    BigDecimal inCoins = new BigDecimal(satoshis).movePointLeft(coinOffset);
    if (inCoins.remainder(ONE).compareTo(ZERO) == 0) {
        places = COIN_SCALE;
    } else {
        BigDecimal inMillis = inCoins.movePointRight(MILLICOIN_SCALE);
        if (inMillis.remainder(ONE).compareTo(ZERO) == 0) {
            places = MILLICOIN_SCALE;
        } else {
            BigDecimal inMicros = inCoins.movePointRight(MICROCOIN_SCALE);
            if (inMicros.remainder(ONE).compareTo(ZERO) == 0) {
                places = MICROCOIN_SCALE;
            } else {
                // no way to avoid rounding: so what denomination gives smallest error?
                BigDecimal a = inCoins.subtract(inCoins.setScale(0, HALF_UP)).
                               movePointRight(coinOffset).abs();
                BigDecimal b = inMillis.subtract(inMillis.setScale(0, HALF_UP)).
                               movePointRight(coinOffset - MILLICOIN_SCALE).abs();
                BigDecimal c = inMicros.subtract(inMicros.setScale(0, HALF_UP)).
                               movePointRight(coinOffset - MICROCOIN_SCALE).abs();
                if (a.compareTo(b) < 0)
                    if (a.compareTo(c) < 0) places = COIN_SCALE;
                    else places = MICROCOIN_SCALE;
                else if (b.compareTo(c) < 0) places = MILLICOIN_SCALE;
                else places = MICROCOIN_SCALE;
            }
        }
    }
    prefixUnitsIndicator(numberFormat, places);
    return places;
}
 
Example 17
Source File: GenBeans.java    From netbeans with Apache License 2.0 4 votes vote down vote up
public void setTarget(String value) {
    BigDecimal num = new BigDecimal(value);
    num = num.movePointRight(2);
    jdkTarget = num.intValue();
}
 
Example 18
Source File: BtcAutoFormat.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Calculate the appropriate denomination for the given Bitcoin monetary value.  This
 * method takes a BigInteger representing a quantity of satoshis, and returns the
 * number of places that value's decimal point is to be moved when formatting said value
 * in order that the resulting number represents the correct quantity of denominational
 * units.
 * <p>
 * <p>As a side-effect, this sets the units indicators of the underlying NumberFormat object.
 * Only invoke this from a synchronized method, and be sure to put the DecimalFormatSymbols
 * back to its proper state, otherwise immutability, equals() and hashCode() fail.
 */
@Override
protected int scale(BigInteger satoshis, int fractionPlaces) {
    /* The algorithm is as follows.  TODO: is there a way to optimize step 4?
       1. Can we use coin denomination w/ no rounding?  If yes, do it.
       2. Else, can we use millicoin denomination w/ no rounding? If yes, do it.
       3. Else, can we use micro denomination w/ no rounding?  If yes, do it.
       4. Otherwise we must round:
         (a) round to nearest coin + decimals
         (b) round to nearest millicoin + decimals
         (c) round to nearest microcoin + decimals
         Subtract each of (a), (b) and (c) from the true value, and choose the
         denomination that gives smallest absolute difference.  It case of tie, use the
         smaller denomination.
    */
    int places;
    int coinOffset = Math.max(SMALLEST_UNIT_EXPONENT - fractionPlaces, 0);
    BigDecimal inCoins = new BigDecimal(satoshis).movePointLeft(coinOffset);
    if (inCoins.remainder(ONE).compareTo(ZERO) == 0) {
        places = COIN_SCALE;
    } else {
        BigDecimal inMillis = inCoins.movePointRight(MILLICOIN_SCALE);
        if (inMillis.remainder(ONE).compareTo(ZERO) == 0) {
            places = MILLICOIN_SCALE;
        } else {
            BigDecimal inMicros = inCoins.movePointRight(MICROCOIN_SCALE);
            if (inMicros.remainder(ONE).compareTo(ZERO) == 0) {
                places = MICROCOIN_SCALE;
            } else {
                // no way to avoid rounding: so what denomination gives smallest error?
                BigDecimal a = inCoins.subtract(inCoins.setScale(0, HALF_UP)).
                        movePointRight(coinOffset).abs();
                BigDecimal b = inMillis.subtract(inMillis.setScale(0, HALF_UP)).
                        movePointRight(coinOffset - MILLICOIN_SCALE).abs();
                BigDecimal c = inMicros.subtract(inMicros.setScale(0, HALF_UP)).
                        movePointRight(coinOffset - MICROCOIN_SCALE).abs();
                if (a.compareTo(b) < 0)
                    if (a.compareTo(c) < 0)
                        places = COIN_SCALE;
                    else
                        places = MICROCOIN_SCALE;
                else if (b.compareTo(c) < 0)
                    places = MILLICOIN_SCALE;
                else
                    places = MICROCOIN_SCALE;
            }
        }
    }
    prefixUnitsIndicator(numberFormat, places);
    return places;
}
 
Example 19
Source File: Temperature.java    From openhab1-addons with Eclipse Public License 2.0 2 votes vote down vote up
/**
 * Factory method to construct a Temperature from Fahrenheit.
 * 
 * @param fahrenheit
 *            the Fahrenheit temperature
 */
public static Temperature fromFahrenheit(BigDecimal fahrenheit) {
    return new Temperature(fahrenheit.movePointRight(1));
}