diff --git a/core/src/main/java/org/bitcoinj/core/Coin.java b/core/src/main/java/org/bitcoinj/core/Coin.java index 0e2d19d0..7f2fb0f9 100644 --- a/core/src/main/java/org/bitcoinj/core/Coin.java +++ b/core/src/main/java/org/bitcoinj/core/Coin.java @@ -116,12 +116,16 @@ public final class Coin implements Monetary, Comparable, Serializable { } /** - * Parses an amount expressed in the way humans are used to.

+ *

+ * Parses an amount expressed in the way humans are used to. *

- * This takes string in a format understood by {@link BigDecimal#BigDecimal(String)}, - * for example "0", "1", "0.10", "1.23E3", "1234.5E-5". + *

+ * This takes string in a format understood by {@link BigDecimal#BigDecimal(String)}, for example "0", "1", "0.10", + * "1.23E3", "1234.5E-5". + *

* - * @throws IllegalArgumentException if you try to specify fractional satoshis, or a value out of range. + * @throws IllegalArgumentException + * if you try to specify fractional satoshis, or a value out of range. */ public static Coin parseCoin(final String str) { try { @@ -132,6 +136,27 @@ public final class Coin implements Monetary, Comparable, Serializable { } } + /** + *

+ * Parses an amount expressed in the way humans are used to. The amount is cut to satoshi precision. + *

+ *

+ * This takes string in a format understood by {@link BigDecimal#BigDecimal(String)}, for example "0", "1", "0.10", + * "1.23E3", "1234.5E-5". + *

+ * + * @throws IllegalArgumentException + * if you try to specify a value out of range. + */ + public static Coin parseCoinInexact(final String str) { + try { + long satoshis = new BigDecimal(str).movePointRight(SMALLEST_UNIT_EXPONENT).longValue(); + return Coin.valueOf(satoshis); + } catch (ArithmeticException e) { + throw new IllegalArgumentException(e); // Repackage exception to honor method contract + } + } + public Coin add(final Coin value) { return new Coin(LongMath.checkedAdd(this.value, value.value)); } diff --git a/core/src/main/java/org/bitcoinj/utils/Fiat.java b/core/src/main/java/org/bitcoinj/utils/Fiat.java index 354bb9b4..fc49e7b8 100644 --- a/core/src/main/java/org/bitcoinj/utils/Fiat.java +++ b/core/src/main/java/org/bitcoinj/utils/Fiat.java @@ -73,12 +73,14 @@ public final class Fiat implements Monetary, Comparable, Serializable { } /** - * Parses an amount expressed in the way humans are used to. *

+ * Parses an amount expressed in the way humans are used to. *

+ *

* This takes string in a format understood by {@link BigDecimal#BigDecimal(String)}, for example "0", "1", "0.10", * "1.23E3", "1234.5E-5". - * + *

+ * * @throws IllegalArgumentException * if you try to specify more than 4 digits after the comma, or a value out of range. */ @@ -91,6 +93,27 @@ public final class Fiat implements Monetary, Comparable, Serializable { } } + /** + *

+ * Parses an amount expressed in the way humans are used to. The amount is cut to 4 digits after the comma. + *

+ *

+ * This takes string in a format understood by {@link BigDecimal#BigDecimal(String)}, for example "0", "1", "0.10", + * "1.23E3", "1234.5E-5". + *

+ * + * @throws IllegalArgumentException + * if you try to specify a value out of range. + */ + public static Fiat parseFiatInexact(final String currencyCode, final String str) { + try { + long val = new BigDecimal(str).movePointRight(SMALLEST_UNIT_EXPONENT).longValue(); + return Fiat.valueOf(currencyCode, val); + } catch (ArithmeticException e) { + throw new IllegalArgumentException(e); + } + } + public Fiat add(final Fiat value) { checkArgument(value.currencyCode.equals(currencyCode)); return new Fiat(currencyCode, LongMath.checkedAdd(this.value, value.value)); diff --git a/core/src/test/java/org/bitcoinj/core/CoinTest.java b/core/src/test/java/org/bitcoinj/core/CoinTest.java index a741caf4..018fa08b 100644 --- a/core/src/test/java/org/bitcoinj/core/CoinTest.java +++ b/core/src/test/java/org/bitcoinj/core/CoinTest.java @@ -42,6 +42,19 @@ public class CoinTest { } catch (Exception e) { org.junit.Assert.fail("should throw IllegalArgumentException"); } + assertEquals(1, parseCoin("0.00000001").value); + assertEquals(1, parseCoin("0.000000010").value); + } + + @Test(expected = IllegalArgumentException.class) + public void testParseCoinOverprecise() { + parseCoin("0.000000011"); + } + + @Test + public void testParseCoinInexact() { + assertEquals(1, parseCoinInexact("0.00000001").value); + assertEquals(1, parseCoinInexact("0.000000011").value); } @Test diff --git a/core/src/test/java/org/bitcoinj/utils/FiatTest.java b/core/src/test/java/org/bitcoinj/utils/FiatTest.java index 8b89a9c9..0139bf05 100644 --- a/core/src/test/java/org/bitcoinj/utils/FiatTest.java +++ b/core/src/test/java/org/bitcoinj/utils/FiatTest.java @@ -31,6 +31,23 @@ public class FiatTest { assertEquals(Fiat.valueOf("EUR", -10000), parseFiat("EUR", "-1")); } + @Test + public void testParseFiat() { + assertEquals(1, Fiat.parseFiat("EUR", "0.0001").value); + assertEquals(1, Fiat.parseFiat("EUR", "0.00010").value); + } + + @Test(expected = IllegalArgumentException.class) + public void testParseFiatOverprecise() { + Fiat.parseFiat("EUR", "0.00011"); + } + + @Test + public void testParseFiatInexact() { + assertEquals(1, Fiat.parseFiatInexact("EUR", "0.0001").value); + assertEquals(1, Fiat.parseFiatInexact("EUR", "0.00011").value); + } + @Test public void testToFriendlyString() { assertEquals("1.00 EUR", parseFiat("EUR", "1").toFriendlyString());