This is an automated email from the ASF dual-hosted git repository.

aherbert 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 21a7c308 Allow DD creation from an unsigned int value.
21a7c308 is described below

commit 21a7c3085e2c161b0e3e1864abe7786b2a9854f5
Author: Alex Herbert <[email protected]>
AuthorDate: Mon Mar 30 15:44:36 2026 +0100

    Allow DD creation from an unsigned int value.
---
 .../java/org/apache/commons/numbers/core/DD.java   | 33 ++++++++++++++++++----
 .../org/apache/commons/numbers/core/DDTest.java    | 27 ++++++++++++++++--
 src/changes/changes.xml                            |  2 +-
 3 files changed, 53 insertions(+), 9 deletions(-)

diff --git 
a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/DD.java 
b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/DD.java
index f92d2805..b7e29796 100644
--- a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/DD.java
+++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/DD.java
@@ -325,7 +325,7 @@ public final class DD
     /**
      * Creates the double-double number as the value {@code (x, 0)}.
      *
-     * <p>Note this method exists to avoid using {@link #of(long)} for {@code 
integer}
+     * <p>Note this method exists to avoid using {@link #of(long)} for {@code 
int}
      * arguments; the {@code long} variation is slower as it preserves all 
64-bits
      * of information.
      *
@@ -363,13 +363,36 @@ public final class DD
 
     /**
      * Creates the double-double number using the argument {@code x} as an 
unsigned
-     * 64-bit integer.
+     * 32-bit integer. Equivalent to:
      *
-     * <p>Note this method preserves all 64-bits of precision. It can be used 
to
-     * represent the positive difference between two ordered {@code long} 
values
-     * without using {@link DD#subtract(DD)}.
+     * <pre>
+     * DD.of((double) Integer.toUnsignedLong(x))
+     * </pre>
+     *
+     * <p>Note this method exists to avoid using {@link #ofUnsigned(long)} for 
{@code int}
+     * arguments as sign extension on negative values will generate an 
incorrect result.
+     *
+     * @param x Value.
+     * @return the double-double
+     */
+    public static DD ofUnsigned(int x) {
+        return new DD(Integer.toUnsignedLong(x), 0);
+    }
+
+    /**
+     * Creates the double-double number using the argument {@code x} as an 
unsigned 64-bit
+     * integer.
+     *
+     * <p>Zero and positive values are mapped to a numerically equal 
double-double value;
+     * and negative values are mapped to a value equal to the positive {@code 
long} value
+     * of the low order 63-bits plus 2<sup>63</sup>.
+     *
+     * <p>Note this method preserves all 64-bits of precision. It can be used 
to represent
+     * the positive difference between two ordered {@code long} values without 
using
+     * {@link DD#subtract(DD)}.
      *
      * <p>Given two {@code long} values {@code a <= b} the following are 
equivalent:
+     *
      * <pre>
      * DD.of(b).subtract(DD.of(a))
      *
diff --git 
a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/DDTest.java
 
b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/DDTest.java
index c1cd2331..06b047e2 100644
--- 
a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/DDTest.java
+++ 
b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/DDTest.java
@@ -27,7 +27,6 @@ import java.util.function.IntSupplier;
 import java.util.function.Supplier;
 import java.util.function.UnaryOperator;
 import java.util.stream.IntStream;
-import java.util.stream.LongStream;
 import java.util.stream.Stream;
 import org.apache.commons.rng.UniformRandomProvider;
 import org.apache.commons.rng.simple.RandomSource;
@@ -145,6 +144,28 @@ class DDTest {
         
Assertions.assertEquals(BigDecimal.valueOf(-x).subtract(bd(-x)).doubleValue(), 
dd.lo(), "-x lo should be remaining bits");
     }
 
+    /**
+     * Test conversion of an unsigned {@code int}.
+     */
+    @ParameterizedTest
+    @ValueSource(ints = {0, 1, 42, 89545664,
+        -1, -42, -89545664,
+        Integer.MAX_VALUE - (1 << 10), Integer.MAX_VALUE - 42, 
Integer.MAX_VALUE - 1, Integer.MAX_VALUE,
+        Integer.MIN_VALUE + (1 << 10), Integer.MIN_VALUE + 42, 
Integer.MIN_VALUE + 1, Integer.MIN_VALUE})
+    @MethodSource
+    void testOfUnsignedInt(int x) {
+        final DD dd = DD.ofUnsigned(x);
+        Assertions.assertTrue(dd.hi() >= 0, "x hi should be positive");
+        final double expected = Integer.toUnsignedLong(x);
+        Assertions.assertEquals(expected, dd.hi(), "x hi");
+        Assertions.assertEquals(0, dd.lo(), "x lo");
+    }
+
+    static int[] testOfUnsignedInt() {
+        // Random
+        return createRNG().ints(10).toArray();
+    }
+
     /**
      * Test conversion of an unsigned {@code long}.
      */
@@ -172,9 +193,9 @@ class DDTest {
         Assertions.assertEquals(lo, dd.lo(), "x lo");
     }
 
-    static LongStream testOfUnsignedLong() {
+    static long[] testOfUnsignedLong() {
         // Random
-        return createRNG().longs(10);
+        return createRNG().longs(10).toArray();
     }
 
     @ParameterizedTest
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index bc8fb6ab..dde1face 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -57,7 +57,7 @@ If the output is not quite correct, check for invisible 
trailing spaces!
 New features, updates and bug fixes.
 ">
       <action dev="aherbert" type="add">
-        "DD": Allow creation from an unsigned long value.
+        "DD": Allow creation from an unsigned int or long value.
       </action>
       <action dev="aherbert" type="add" issue="NUMBERS-208">
         "Selection": Add support for selection from a long array.

Reply via email to