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>

Reply via email to