MonetaryFormat { public CharSequence format(Monetary monetary) { int maxDecimals = minDecimals; if (decimalGroups != null) for (int group : decimalGroups) maxDecimals += group; int smallestUnitExponent = monetary.smallestUnitExponent(); checkState(maxDecimals <= smallestUnitExponent, "The maximum possible number of decimals (%s) cannot exceed %s.", maxDecimals, smallestUnitExponent); long satoshis = Math.abs(monetary.getValue()); long precisionDivisor = checkedPow(10, smallestUnitExponent - shift - maxDecimals); satoshis = checkedMultiply(divide(satoshis, precisionDivisor, roundingMode), precisionDivisor); long shiftDivisor = checkedPow(10, smallestUnitExponent - shift); long numbers = satoshis / shiftDivisor; long decimals = satoshis % shiftDivisor; String decimalsStr = String.format(Locale.US, "%0" + (smallestUnitExponent - shift) + "d", decimals); StringBuilder str = new StringBuilder(decimalsStr); while (str.length() > minDecimals && str.charAt(str.length() - 1) == '0') str.setLength(str.length() - 1); int i = minDecimals; if (decimalGroups != null) { for (int group : decimalGroups) { if (str.length() > i && str.length() < i + group) { while (str.length() < i + group) str.append('0'); break; } i += group; } } if (str.length() > 0) str.insert(0, decimalMark); str.insert(0, numbers); if (monetary.getValue() < 0) str.insert(0, negativeSign); else if (positiveSign != 0) str.insert(0, positiveSign); if (codes != null) { if (codePrefixed) { str.insert(0, codeSeparator); str.insert(0, code()); } else { str.append(codeSeparator); str.append(code()); } } if (zeroDigit != '0') { int offset = zeroDigit - '0'; for (int d = 0; d < str.length(); d++) { char c = str.charAt(d); if (Character.isDigit(c)) str.setCharAt(d, (char) (c + offset)); } } return str; } MonetaryFormat(); private  MonetaryFormat(char negativeSign, char positiveSign, char zeroDigit, char decimalMark, int minDecimals,
            List<Integer> decimalGroups, int shift, RoundingMode roundingMode, String[] codes,
            char codeSeparator, boolean codePrefixed); MonetaryFormat negativeSign(char negativeSign); MonetaryFormat positiveSign(char positiveSign); MonetaryFormat digits(char zeroDigit); MonetaryFormat decimalMark(char decimalMark); MonetaryFormat minDecimals(int minDecimals); MonetaryFormat optionalDecimals(int... groups); MonetaryFormat repeatOptionalDecimals(int decimals, int repetitions); MonetaryFormat shift(int shift); MonetaryFormat roundingMode(RoundingMode roundingMode); MonetaryFormat noCode(); MonetaryFormat code(int codeShift, String code); MonetaryFormat codeSeparator(char codeSeparator); MonetaryFormat prefixCode(); MonetaryFormat postfixCode(); MonetaryFormat withLocale(Locale locale); CharSequence format(Monetary monetary); Coin parse(String str); Fiat parseFiat(String currencyCode, String str); String code(); @Override boolean equals(final Object o); @Override int hashCode(); static final MonetaryFormat BTC; static final MonetaryFormat MBTC; static final MonetaryFormat UBTC; static final MonetaryFormat FIAT; static final String CODE_BTC; static final String CODE_MBTC; static final String CODE_UBTC; static final int MAX_DECIMALS; }
@Test public void testGrouping() throws Exception { assertEquals("0.1", format(Coin.parseCoin("0.1"), 0, 1, 2, 3)); assertEquals("0.010", format(Coin.parseCoin("0.01"), 0, 1, 2, 3)); assertEquals("0.001", format(Coin.parseCoin("0.001"), 0, 1, 2, 3)); assertEquals("0.000100", format(Coin.parseCoin("0.0001"), 0, 1, 2, 3)); assertEquals("0.000010", format(Coin.parseCoin("0.00001"), 0, 1, 2, 3)); assertEquals("0.000001", format(Coin.parseCoin("0.000001"), 0, 1, 2, 3)); }
@Test public void btcRounding() throws Exception { assertEquals("0", format(ZERO, 0, 0)); assertEquals("0.00", format(ZERO, 0, 2)); assertEquals("1", format(COIN, 0, 0)); assertEquals("1.0", format(COIN, 0, 1)); assertEquals("1.00", format(COIN, 0, 2, 2)); assertEquals("1.00", format(COIN, 0, 2, 2, 2)); assertEquals("1.00", format(COIN, 0, 2, 2, 2, 2)); assertEquals("1.000", format(COIN, 0, 3)); assertEquals("1.0000", format(COIN, 0, 4)); final Coin justNot = COIN.subtract(SATOSHI); assertEquals("1", format(justNot, 0, 0)); assertEquals("1.0", format(justNot, 0, 1)); assertEquals("1.00", format(justNot, 0, 2, 2)); assertEquals("1.00", format(justNot, 0, 2, 2, 2)); assertEquals("0.99999999", format(justNot, 0, 2, 2, 2, 2)); assertEquals("1.000", format(justNot, 0, 3)); assertEquals("1.0000", format(justNot, 0, 4)); final Coin slightlyMore = COIN.add(SATOSHI); assertEquals("1", format(slightlyMore, 0, 0)); assertEquals("1.0", format(slightlyMore, 0, 1)); assertEquals("1.00", format(slightlyMore, 0, 2, 2)); assertEquals("1.00", format(slightlyMore, 0, 2, 2, 2)); assertEquals("1.00000001", format(slightlyMore, 0, 2, 2, 2, 2)); assertEquals("1.000", format(slightlyMore, 0, 3)); assertEquals("1.0000", format(slightlyMore, 0, 4)); final Coin pivot = COIN.add(SATOSHI.multiply(5)); assertEquals("1.00000005", format(pivot, 0, 8)); assertEquals("1.00000005", format(pivot, 0, 7, 1)); assertEquals("1.0000001", format(pivot, 0, 7)); final Coin value = Coin.valueOf(1122334455667788l); assertEquals("11223345", format(value, 0, 0)); assertEquals("11223344.6", format(value, 0, 1)); assertEquals("11223344.5567", format(value, 0, 2, 2)); assertEquals("11223344.556678", format(value, 0, 2, 2, 2)); assertEquals("11223344.55667788", format(value, 0, 2, 2, 2, 2)); assertEquals("11223344.557", format(value, 0, 3)); assertEquals("11223344.5567", format(value, 0, 4)); }
@Test public void mBtcRounding() throws Exception { assertEquals("0", format(ZERO, 3, 0)); assertEquals("0.00", format(ZERO, 3, 2)); assertEquals("1000", format(COIN, 3, 0)); assertEquals("1000.0", format(COIN, 3, 1)); assertEquals("1000.00", format(COIN, 3, 2)); assertEquals("1000.00", format(COIN, 3, 2, 2)); assertEquals("1000.000", format(COIN, 3, 3)); assertEquals("1000.0000", format(COIN, 3, 4)); final Coin justNot = COIN.subtract(SATOSHI.multiply(10)); assertEquals("1000", format(justNot, 3, 0)); assertEquals("1000.0", format(justNot, 3, 1)); assertEquals("1000.00", format(justNot, 3, 2)); assertEquals("999.9999", format(justNot, 3, 2, 2)); assertEquals("1000.000", format(justNot, 3, 3)); assertEquals("999.9999", format(justNot, 3, 4)); final Coin slightlyMore = COIN.add(SATOSHI.multiply(10)); assertEquals("1000", format(slightlyMore, 3, 0)); assertEquals("1000.0", format(slightlyMore, 3, 1)); assertEquals("1000.00", format(slightlyMore, 3, 2)); assertEquals("1000.000", format(slightlyMore, 3, 3)); assertEquals("1000.0001", format(slightlyMore, 3, 2, 2)); assertEquals("1000.0001", format(slightlyMore, 3, 4)); final Coin pivot = COIN.add(SATOSHI.multiply(50)); assertEquals("1000.0005", format(pivot, 3, 4)); assertEquals("1000.0005", format(pivot, 3, 3, 1)); assertEquals("1000.001", format(pivot, 3, 3)); final Coin value = Coin.valueOf(1122334455667788l); assertEquals("11223344557", format(value, 3, 0)); assertEquals("11223344556.7", format(value, 3, 1)); assertEquals("11223344556.68", format(value, 3, 2)); assertEquals("11223344556.6779", format(value, 3, 2, 2)); assertEquals("11223344556.678", format(value, 3, 3)); assertEquals("11223344556.6779", format(value, 3, 4)); }
@Test public void uBtcRounding() throws Exception { assertEquals("0", format(ZERO, 6, 0)); assertEquals("0.00", format(ZERO, 6, 2)); assertEquals("1000000", format(COIN, 6, 0)); assertEquals("1000000", format(COIN, 6, 0, 2)); assertEquals("1000000.0", format(COIN, 6, 1)); assertEquals("1000000.00", format(COIN, 6, 2)); final Coin justNot = COIN.subtract(SATOSHI); assertEquals("1000000", format(justNot, 6, 0)); assertEquals("999999.99", format(justNot, 6, 0, 2)); assertEquals("1000000.0", format(justNot, 6, 1)); assertEquals("999999.99", format(justNot, 6, 2)); final Coin slightlyMore = COIN.add(SATOSHI); assertEquals("1000000", format(slightlyMore, 6, 0)); assertEquals("1000000.01", format(slightlyMore, 6, 0, 2)); assertEquals("1000000.0", format(slightlyMore, 6, 1)); assertEquals("1000000.01", format(slightlyMore, 6, 2)); final Coin pivot = COIN.add(SATOSHI.multiply(5)); assertEquals("1000000.05", format(pivot, 6, 2)); assertEquals("1000000.05", format(pivot, 6, 0, 2)); assertEquals("1000000.1", format(pivot, 6, 1)); assertEquals("1000000.1", format(pivot, 6, 0, 1)); final Coin value = Coin.valueOf(1122334455667788l); assertEquals("11223344556678", format(value, 6, 0)); assertEquals("11223344556677.88", format(value, 6, 2)); assertEquals("11223344556677.9", format(value, 6, 1)); assertEquals("11223344556677.88", format(value, 6, 2)); }
@Test public void standardCodes() throws Exception { assertEquals("BTC 0.00", MonetaryFormat.BTC.format(Coin.ZERO).toString()); assertEquals("mBTC 0.00", MonetaryFormat.MBTC.format(Coin.ZERO).toString()); assertEquals("µBTC 0", MonetaryFormat.UBTC.format(Coin.ZERO).toString()); }