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.