Skip to content

Commit

Permalink
Avoid Price.toString() failing for certain values of numerator/denomi…
Browse files Browse the repository at this point in the history
…nator.

Fixes a regression introduced in 66cc533 (bugfix #479) in which the
numerator/denominator division fails with an ArithmeticException if no
MathContext is provided. BigDecimal tries to return an exact result,
which is not possible when rounding and precision aren't specified.

See BigDecimal javadoc:
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

Fixes Crashlitics issue #196
https://fabric.io/gnucash/android/apps/org.gnucash.android/issues/571b4a95ffcdc04250f98ba0
  • Loading branch information
rivaldi8 committed Apr 24, 2016
1 parent c0d00e1 commit fd7007e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
3 changes: 2 additions & 1 deletion app/src/main/java/org/gnucash/android/model/Price.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


import java.math.BigDecimal;
import java.math.MathContext;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.NumberFormat;
Expand Down Expand Up @@ -156,6 +157,6 @@ public String toString() {
BigDecimal denominator = new BigDecimal(mValueDenom);
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance();
formatter.setMaximumFractionDigits(6);
return formatter.format(numerator.divide(denominator));
return formatter.format(numerator.divide(denominator, MathContext.DECIMAL32));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Locale;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;


public class PriceTest {
Expand Down Expand Up @@ -52,6 +53,26 @@ public void toString_shouldUseDefaultLocale() {
assertThat(price.toString()).isEqualTo("1,234");
}

/**
* BigDecimal throws an ArithmeticException if it can't represent exactly
* a result. This can happen with divisions like 1/3 if no precision and
* round mode is specified with a MathContext.
*/
@Test
public void toString_shouldNotFailForInfinitelyLongDecimalExpansion() {
long numerator = 1;
long denominator = 3;
Price price = new Price();

price.setValueNum(numerator);
price.setValueDenom(denominator);
try {
price.toString();
} catch (ArithmeticException e) {
fail("The numerator/denominator division in Price.toString() should not fail.");
}
}

@Test
public void getNumerator_shouldReduceAutomatically() {
long numerator = 1;
Expand Down

0 comments on commit fd7007e

Please sign in to comment.