This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
The following commit(s) were added to refs/heads/master by this push:
new f928a893 NUMBERS-217: BigFraction conversion using a MathContext
f928a893 is described below
commit f928a893d0aac6c9f0baaade9629df800005a187
Author: Alex Herbert <[email protected]>
AuthorDate: Sat Sep 26 09:11:54 2026 +0100
NUMBERS-217: BigFraction conversion using a MathContext
---
.../commons/numbers/fraction/BigFraction.java | 18 ++++++++++++++++
.../commons/numbers/fraction/BigFractionTest.java | 25 ++++++++++++++++++++++
src/changes/changes.xml | 3 +++
3 files changed, 46 insertions(+)
diff --git
a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index 22399578..67de54de 100644
---
a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++
b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -19,6 +19,7 @@ package org.apache.commons.numbers.fraction;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Objects;
import org.apache.commons.numbers.core.NativeOperators;
@@ -705,6 +706,23 @@ public final class BigFraction
return new BigDecimal(numerator).divide(new BigDecimal(denominator),
scale, roundingMode);
}
+ /**
+ * Returns the {@code BigDecimal} representation of this fraction.
+ * This calculates the fraction as numerator divided by denominator
+ * with rounding according to the context settings.
+ *
+ * @param mc the context to apply.
+ * @return the fraction as a {@code BigDecimal}.
+ * @throws ArithmeticException if the result is inexact but the rounding
mode is
+ * {@code UNNECESSARY} or {@code mc.precision == 0} and the quotient has a
non-terminating
+ * decimal expansion, including dividing by zero
+ * @see BigDecimal#divide(BigDecimal, MathContext)
+ * @since 1.4
+ */
+ public BigDecimal bigDecimalValue(MathContext mc) {
+ return new BigDecimal(numerator).divide(new BigDecimal(denominator),
mc);
+ }
+
/**
* Adds the specified {@code value} to this fraction, returning
* the result in reduced form.
diff --git
a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index ae6a6d8a..1f0527e6 100644
---
a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++
b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -18,6 +18,7 @@ package org.apache.commons.numbers.fraction;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Arrays;
import org.apache.commons.numbers.core.TestUtils;
@@ -506,6 +507,30 @@ class BigFractionTest {
Assertions.assertEquals(new BigDecimal("0.333"), BigFraction.of(1,
3).bigDecimalValue(3, RoundingMode.DOWN));
}
+ @Test
+ void testBigDecimalValueMathContext() {
+ Assertions.assertEquals(new BigDecimal(0.5), BigFraction.of(1,
2).bigDecimalValue(MathContext.DECIMAL32));
+
+ // 7 digits of precision
+ final BigFraction third = BigFraction.of(1, 3);
+ Assertions.assertEquals(new BigDecimal("0.3333333"),
third.bigDecimalValue(MathContext.DECIMAL32));
+
+ // 1e-20 is not a representable double
+ BigFraction f = BigFraction.of(
+ BigInteger.ONE,
+ new BigInteger("100000000000000000000")
+ );
+ Assertions.assertEquals(new BigDecimal("1e-20"),
f.bigDecimalValue(MathContext.DECIMAL64));
+ Assertions.assertNotEquals(new BigDecimal(1e-20),
f.bigDecimalValue(MathContext.UNLIMITED),
+ "1e20 as a double is not representable");
+
+ // Check the exceptions from BigDecimal divide
+ // MathContext.UNLIMITED has precision 0
+ Assertions.assertThrows(ArithmeticException.class, () ->
third.bigDecimalValue(MathContext.UNLIMITED));
+ final MathContext mc = new MathContext(10, RoundingMode.UNNECESSARY);
+ Assertions.assertThrows(ArithmeticException.class, () ->
third.bigDecimalValue(mc));
+ }
+
@Test
void testAbs() {
for (final CommonTestCases.UnaryOperatorTestCase testCase :
CommonTestCases.absTestCases()) {
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 7093bd58..4aabcfc4 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -56,6 +56,9 @@ If the output is not quite correct, check for invisible
trailing spaces!
<release version="1.4" date="TBD" description="
New features, updates and bug fixes.
">
+ <action dev="aherbert" type="add" due-to="Alex Herbert"
issue="NUMBERS-217">
+ "BigFraction": Allow conversion to BigDecimal using a MathContext.
+ </action>
<action dev="erans" type="add" issue="NUMBERS-215">
Nested class "S2" in "o.a.c.numbers.combinatorics.Stirling" for
iterating over k-partitions.
</action>