diff --git a/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/main/java/dev/obrienlabs/performance/nbi/Collatz128bit.java b/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/main/java/dev/obrienlabs/performance/nbi/Collatz128bit.java index 40deb1a..d6e8b15 100644 --- a/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/main/java/dev/obrienlabs/performance/nbi/Collatz128bit.java +++ b/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/main/java/dev/obrienlabs/performance/nbi/Collatz128bit.java @@ -10,6 +10,7 @@ /** * 20250101 * Michael O'Brien michael at obrienlabs.dev + * Code from https://github.com/ObrienlabsDev/performance * * Architecture * map the search space by interleaved UOW (1,3,5,7) - to 4 threads @@ -117,7 +118,8 @@ public void searchCollatzParallel(long oddSearchCurrent, long secondsStart) { .filter(num -> isCollatzMax(num, secondsStart)) .collect(Collectors.toList()); - results.stream().sorted().forEach(x -> System.out.println(x)); + results.stream().forEach(x -> System.out.println(x)); // fix comparable in https://github.com/ObrienlabsDev/performance/issues/27 + //results.stream().sorted().forEach(x -> System.out.println(x)); } System.out.println("last number: " + ((1 + (batches) * threads) - 1)); } diff --git a/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/main/java/dev/obrienlabs/performance/nbi/math/ULong128Impl.java b/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/main/java/dev/obrienlabs/performance/nbi/math/ULong128Impl.java index 6eae1f9..eb55b7e 100644 --- a/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/main/java/dev/obrienlabs/performance/nbi/math/ULong128Impl.java +++ b/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/main/java/dev/obrienlabs/performance/nbi/math/ULong128Impl.java @@ -34,29 +34,54 @@ public boolean isEven() { @Override public boolean isGreaterThan(ULong128 ulong128) { - return false; + // check high (fast exit), then low + int topCompare = Long.compareUnsigned(this.long1, ulong128.getLong1()); + + if(topCompare < 0) { + return false; + } else { + if(topCompare > 0) { + return true; + } else { + int lowCompare = Long.compareUnsigned(this.long0, ulong128.getLong0()); + if(lowCompare < 0) { + return false; + } else { + if(lowCompare > 0) { + return true; + } else { + return false; + } + } + } + } } @Override // we add the low bytes, detect the carry, add the high bytes and add the carry public ULong128 add(ULong128 ulong128) {; - long temp0 = this.getLong0() + ulong128.getLong0(); + long temp0 = this.long0 + ulong128.getLong0(); // a smaller result means we experienced overflow long carry0 = Long.compareUnsigned(temp0, this.getLong0()) < 0 ? 1L : 0L; - long temp1 = this.getLong1() + ulong128.getLong1() + carry0; + long temp1 = this.long1 + ulong128.getLong1() + carry0; return new ULong128Impl(temp1, temp0); } @Override + // use >>> triple shift to fill 0's on the right public ULong128 shiftLeft(int positions) { - ULong128 result = this; - return result; + // we only shift one digit + return this.add(this); } @Override + // use >>> triple shift to fill 0's on the right public ULong128 shiftRight(int positions) { - ULong128 result = this; - return result; + // multiply by 2 until we have the last LSB shifted to MSBit left position + long highShiftedLeft63BitsInPrepOfAddToLow = this.long1 << 63;//(64 - positions); + long temp0 = (this.long0 >>> 1) + highShiftedLeft63BitsInPrepOfAddToLow ; + long temp1 = this.long1 >>> 1; + return new ULong128Impl(temp1, temp0); } @Override diff --git a/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/test/java/dev/obrienlabs/performance/nbi/CollatzTest.java b/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/test/java/dev/obrienlabs/performance/nbi/CollatzTest.java index fbf640e..c81763a 100644 --- a/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/test/java/dev/obrienlabs/performance/nbi/CollatzTest.java +++ b/cpu/virtual/multithreaded/128bit/java-benchmark-128-cli/performance-nbi/src/test/java/dev/obrienlabs/performance/nbi/CollatzTest.java @@ -1,5 +1,6 @@ package dev.obrienlabs.performance.nbi; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -50,4 +51,59 @@ void test128bitAddAtBit31NoOverflow() { assertTrue(c.getLong1() == expected.getLong1()); assertTrue(c.getLong0() == expected.getLong0()); } + + @Test + void testGreaterThanDoubleLongTrue() { + ULong128 a = new ULong128Impl(1L, Long.MAX_VALUE); // 2^31-1 = 9223372036854775807 + ULong128 b = new ULong128Impl(0L, 65536L); + assertTrue(a.isGreaterThan(b)); + } + + @Test + void testGreaterThanDoubleLongFalse() { + ULong128 a = new ULong128Impl(1L, Long.MAX_VALUE); // 2^31-1 = 9223372036854775807 + ULong128 b = new ULong128Impl(0L, 65536L); + assertFalse(b.isGreaterThan(a)); + } + + @Test + void testGreaterThanSingleLongTrue() { + ULong128 a = new ULong128Impl(0L, Long.MAX_VALUE - 2L); // 2^31-1 = 9223372036854775807 + ULong128 b = new ULong128Impl(0L, 65536L); + assertTrue(a.isGreaterThan(b)); + } + + @Test + void testGreaterThanSingleLongFalse() { + ULong128 a = new ULong128Impl(0L, Long.MAX_VALUE - 2L); // 2^31-1 = 9223372036854775807 + ULong128 b = new ULong128Impl(0L, 65536L); + assertFalse(b.isGreaterThan(a)); + } + + @Test + void test128bitShiftLeftWithoutOverflow() { + ULong128 a = new ULong128Impl(2L, 3L); + ULong128 expected = new ULong128Impl(4L, 6L); + ULong128 c = a.shiftLeft(1); + assertTrue(c.getLong1() == expected.getLong1()); + assertTrue(c.getLong0() == expected.getLong0()); + } + + @Test + void test128bitShiftRightWithOverflow() { + ULong128 a = new ULong128Impl(1L, 1L); + ULong128 expected = new ULong128Impl(0L, -(Long.MAX_VALUE + 1)); + ULong128 c = a.shiftRight(1); + assertTrue(c.getLong1() == expected.getLong1()); + assertTrue(c.getLong0() == expected.getLong0()); + } + + @Test + void test128bitShiftRightWithOverflow2() { + ULong128 a = new ULong128Impl(170L, 170L); + ULong128 expected = new ULong128Impl(85L, 85L); + ULong128 c = a.shiftRight(1); + assertTrue(c.getLong1() == expected.getLong1()); + assertTrue(c.getLong0() == expected.getLong0()); + } }