From a0f3ecf3d125be032ffe274ac1ee87df686225ef Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Sun, 3 Nov 2024 15:57:14 -0700 Subject: [PATCH] SWEEP: Replace J2N's TripleShift call with C# 11's unsigned right shift operator, #115 --- Directory.Build.props | 4 +- src/J2N/Collections/BitSet.cs | 25 ++++---- src/J2N/MathExtensions.cs | 6 +- src/J2N/Numerics/BitOperation.cs | 60 +++++++++---------- src/J2N/Numerics/DotNetNumber.Formatting.cs | 15 ++--- src/J2N/Numerics/Double.cs | 2 +- src/J2N/Numerics/Int64.cs | 2 +- src/J2N/Numerics/RyuDouble.cs | 28 ++++----- src/J2N/Randomizer.cs | 4 +- tests/J2N.Tests/Numerics/JDK8/FDBigInteger.cs | 58 ++++++++---------- .../Numerics/JDK8/FloatingDecimal.cs | 20 +++---- .../Numerics/JDK8/OldFDBigIntForTest.cs | 26 ++++---- .../JDK8/OldFloatingDecimalForTest.cs | 11 ++-- .../J2N.Tests/Numerics/Ryu/SlowConversion.cs | 4 +- tests/J2N.Tests/Numerics/TestInt64.cs | 8 +-- 15 files changed, 124 insertions(+), 149 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 35fd981c..8a84ee98 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ $(MSBuildThisFileDirectory) - 10.0 + 11.0 NightOwl888 J2N @@ -43,4 +43,4 @@ true - \ No newline at end of file + diff --git a/src/J2N/Collections/BitSet.cs b/src/J2N/Collections/BitSet.cs index b16b5ed4..36a8498c 100644 --- a/src/J2N/Collections/BitSet.cs +++ b/src/J2N/Collections/BitSet.cs @@ -16,7 +16,6 @@ */ #endregion -using J2N.Numerics; using System; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; @@ -311,11 +310,11 @@ public virtual BitSet Get(int position1, int position2) int idx1 = position1 >> Offset; int idx2 = (position2 - 1) >> Offset; long factor1 = (~0L) << (position1 & RightBits); - long factor2 = (~0L).TripleShift(ElmSize - (position2 & RightBits)); + long factor2 = (~0L) >>> (ElmSize - (position2 & RightBits)); if (idx1 == idx2) { - long result = (bits[idx1] & (factor1 & factor2)).TripleShift(position1 % ElmSize); + long result = (bits[idx1] & (factor1 & factor2)) >>> (position1 % ElmSize); if (result == 0) { return new BitSet(0); @@ -343,7 +342,7 @@ public virtual BitSet Get(int position1, int position2) { // shift the current element to the right regardless of // sign - newbits[i] = newbits[i].TripleShift(numBitsToShift); + newbits[i] >>>= numBitsToShift; // apply the last x bits of newbits[i+1] to the current // element @@ -440,7 +439,7 @@ public virtual void Set(int position1, int position2) int idx1 = position1 >> Offset; int idx2 = (position2 - 1) >> Offset; long factor1 = (~0L) << (position1 & RightBits); - long factor2 = (~0L).TripleShift(ElmSize - (position2 & RightBits)); + long factor2 = (~0L) >>> (ElmSize - (position2 & RightBits)); if (idx1 == idx2) { @@ -572,7 +571,7 @@ public virtual void Clear(int position1, int position2) int idx1 = position1 >> Offset; int idx2 = (position2 - 1) >> Offset; long factor1 = (~0L) << (position1 & RightBits); - long factor2 = (~0L).TripleShift(ElmSize - (position2 & RightBits)); + long factor2 = (~0L) >>> (ElmSize - (position2 & RightBits)); if (idx1 == idx2) { @@ -651,7 +650,7 @@ public virtual void Flip(int position1, int position2) int idx1 = position1 >> Offset; int idx2 = (position2 - 1) >> Offset; long factor1 = (~0L) << (position1 & RightBits); - long factor2 = (~0L).TripleShift(ElmSize - (position2 & RightBits)); + long factor2 = (~0L) >>> (ElmSize - (position2 & RightBits)); if (idx1 == idx2) { @@ -1115,7 +1114,7 @@ public virtual int Cardinality for (int idx = 0; idx < length; idx++) { count += Pop(bits[idx] & 0xffffffffL); - count += Pop(bits[idx].TripleShift(32)); + count += Pop(bits[idx] >>> 32); } return count; } @@ -1124,11 +1123,11 @@ public virtual int Cardinality [SuppressMessage("Style", "IDE0054:Use compound assignment", Justification = "Aligning code style with Apache Harmony")] private static int Pop(long x) { - x = x - (x.TripleShift(1) & 0x55555555); - x = (x & 0x33333333) + ((x.TripleShift(2)) & 0x33333333); - x = (x + (x.TripleShift(4))) & 0x0f0f0f0f; - x = x + (x.TripleShift(8)); - x = x + (x.TripleShift(16)); + x = x - ((x >>> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >>> 2) & 0x33333333); + x = (x + (x >>> 4)) & 0x0f0f0f0f; + x = x + (x >>> 8); + x = x + (x >>> 16); return (int)x & 0x0000003f; } diff --git a/src/J2N/MathExtensions.cs b/src/J2N/MathExtensions.cs index d66eeac9..62acd9ce 100644 --- a/src/J2N/MathExtensions.cs +++ b/src/J2N/MathExtensions.cs @@ -16,13 +16,11 @@ */ #endregion -using J2N.Numerics; using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; - namespace J2N { /// @@ -54,7 +52,7 @@ public static class MathExtensions public static int Signum(this int value) { // HD, Section 2-7 - return (value >> 31) | ((-value).TripleShift(31)); + return (value >> 31) | (-value >>> 31); } /// @@ -68,7 +66,7 @@ public static int Signum(this int value) public static int Signum(this long value) { // HD, Section 2-7 - return (int)((value >> 63) | ((-value).TripleShift(63))); + return (int)((value >> 63) | (-value >>> 63)); } /// diff --git a/src/J2N/Numerics/BitOperation.cs b/src/J2N/Numerics/BitOperation.cs index 0c04df9f..d23a2187 100644 --- a/src/J2N/Numerics/BitOperation.cs +++ b/src/J2N/Numerics/BitOperation.cs @@ -44,11 +44,11 @@ public static int PopCount(this int value) return System.Numerics.BitOperations.PopCount((uint)value); #else // Hacker's Delight, Figure 5-2 - value -= ((value.TripleShift(1)) & 0x55555555); - value = (value & 0x33333333) + ((value.TripleShift(2)) & 0x33333333); - value = (value + (value.TripleShift(4))) & 0x0f0f0f0f; - value += (value.TripleShift(8)); - value += (value.TripleShift(16)); + value -= ((value >>> 1) & 0x55555555); + value = (value & 0x33333333) + ((value >>> 2) & 0x33333333); + value = (value + (value >>> 4)) & 0x0f0f0f0f; + value += (value >>> 8); + value += (value >>> 16); return value & 0x3f; #endif } @@ -67,12 +67,12 @@ public static int PopCount(this long value) return System.Numerics.BitOperations.PopCount((ulong)value); #else // Hacker's Delight, Figure 5-14 - value -= ((value.TripleShift(1)) & 0x5555555555555555L); - value = (value & 0x3333333333333333L) + ((value.TripleShift(2)) & 0x3333333333333333L); - value = (value + (value.TripleShift(4))) & 0x0f0f0f0f0f0f0f0fL; - value += (value.TripleShift(8)); - value += (value.TripleShift(16)); - value += (value.TripleShift(32)); + value -= ((value >>> 1) & 0x5555555555555555L); + value = (value & 0x3333333333333333L) + ((value >>> 2) & 0x3333333333333333L); + value = (value + (value >>> 4)) & 0x0f0f0f0f0f0f0f0fL; + value += (value >>> 8); + value += (value >>> 16); + value += (value >>> 32); return (int)value & 0x7f; #endif } @@ -239,7 +239,7 @@ public static int HighestOneBit(this int value) // Harmony value |= (value >> 4); value |= (value >> 8); value |= (value >> 16); - return (value & ~(value.TripleShift(1))); + return (value & ~(value >>> 1)); } /// @@ -262,7 +262,7 @@ public static long HighestOneBit(this long value) value |= (value >> 8); value |= (value >> 16); value |= (value >> 32); - return (value & ~(value.TripleShift(1))); + return (value & ~(value >>> 1)); } #endregion HighestOneBit @@ -347,11 +347,11 @@ public static long LowestOneBit(this long value) public static int Reverse(this int value) { // From Hacker's Delight, 7-1, Figure 7-1 - value = (value & 0x55555555) << 1 | (value.TripleShift(1)) & 0x55555555; - value = (value & 0x33333333) << 2 | (value.TripleShift(2)) & 0x33333333; - value = (value & 0x0f0f0f0f) << 4 | (value.TripleShift(4)) & 0x0f0f0f0f; + value = (value & 0x55555555) << 1 | (value >>> 1) & 0x55555555; + value = (value & 0x33333333) << 2 | (value >>> 2) & 0x33333333; + value = (value & 0x0f0f0f0f) << 4 | (value >>> 4) & 0x0f0f0f0f; value = (value << 24) | ((value & 0xff00) << 8) | - ((value.TripleShift(8)) & 0xff00) | (value.TripleShift(24)); + ((value >>> 8) & 0xff00) | (value >>> 24); return value; } @@ -365,12 +365,12 @@ public static int Reverse(this int value) public static long Reverse(this long value) { // From Hacker's Delight, 7-1, Figure 7-1 - value = (value & 0x5555555555555555L) << 1 | (value.TripleShift(1)) & 0x5555555555555555L; - value = (value & 0x3333333333333333L) << 2 | (value.TripleShift(2)) & 0x3333333333333333L; - value = (value & 0x0f0f0f0f0f0f0f0fL) << 4 | (value.TripleShift(4)) & 0x0f0f0f0f0f0f0f0fL; - value = (value & 0x00ff00ff00ff00ffL) << 8 | (value.TripleShift(8)) & 0x00ff00ff00ff00ffL; + value = (value & 0x5555555555555555L) << 1 | (value >>> 1) & 0x5555555555555555L; + value = (value & 0x3333333333333333L) << 2 | (value >>> 2) & 0x3333333333333333L; + value = (value & 0x0f0f0f0f0f0f0f0fL) << 4 | (value >>> 4) & 0x0f0f0f0f0f0f0f0fL; + value = (value & 0x00ff00ff00ff00ffL) << 8 | (value >>> 8) & 0x00ff00ff00ff00ffL; value = (value << 48) | ((value & 0xffff0000L) << 16) | - ((value.TripleShift(16)) & 0xffff0000L) | (value.TripleShift(48)); + ((value >>> 16) & 0xffff0000L) | (value >>> 48); return value; } @@ -401,7 +401,7 @@ public static short ReverseBytes(this short value) /// . public static int ReverseBytes(this int value) { - return ((value.TripleShift(24))) | + return ((value >>> 24)) | ((value >> 8) & 0xFF00) | ((value << 8) & 0xFF0000) | ((value << 24)); @@ -417,11 +417,11 @@ public static int ReverseBytes(this int value) public static long ReverseBytes(this long value) { value = (value & 0x00ff00ff00ff00ffL) << 8 | - (value.TripleShift(8)) & 0x00ff00ff00ff00ffL; + (value >>> 8) & 0x00ff00ff00ff00ffL; return (value << 48) | ((value & 0xffff0000L) << 16) | - ((value.TripleShift(16)) & 0xffff0000L) | - (value.TripleShift(48)); + ((value >>> 16) & 0xffff0000L) | + (value >>> 48); } #endregion @@ -459,7 +459,7 @@ public static int RotateLeft(this int value, int distance) #if FEATURE_NUMERICBITOPERATIONS return (int)System.Numerics.BitOperations.RotateLeft((uint)value, distance); #else - return ((value << distance) | (value.TripleShift(-distance))); + return ((value << distance) | (value >>> -distance)); #endif } @@ -497,7 +497,7 @@ public static long RotateLeft(this long value, int distance) #if FEATURE_NUMERICBITOPERATIONS return (long)System.Numerics.BitOperations.RotateLeft((ulong)value, distance); #else - return ((value << distance) | (value.TripleShift(-distance))); + return ((value << distance) | (value >>> -distance)); #endif } @@ -536,7 +536,7 @@ public static int RotateRight(this int value, int distance) #if FEATURE_NUMERICBITOPERATIONS return (int)System.Numerics.BitOperations.RotateRight((uint)value, distance); #else - return ((value.TripleShift(distance)) | (value << (-distance))); + return ((value >>> distance) | (value << (-distance))); #endif } @@ -571,7 +571,7 @@ public static long RotateRight(this long value, int distance) #if FEATURE_NUMERICBITOPERATIONS return (long)System.Numerics.BitOperations.RotateRight((ulong)value, distance); #else - return ((value.TripleShift(distance)) | (value << (-distance))); + return ((value >>> distance) | (value << -distance)); #endif } diff --git a/src/J2N/Numerics/DotNetNumber.Formatting.cs b/src/J2N/Numerics/DotNetNumber.Formatting.cs index 92586cc7..6837ebd2 100644 --- a/src/J2N/Numerics/DotNetNumber.Formatting.cs +++ b/src/J2N/Numerics/DotNetNumber.Formatting.cs @@ -513,7 +513,7 @@ internal static string DoubleToHexStr(double value, NumberFormatInfo info, bool bool negative = (bitValue & unchecked((long)0x8000000000000000L)) != 0; // mask exponent bits and shift down - long exponent = (bitValue & 0x7FF0000000000000L).TripleShift(52); + long exponent = (bitValue & 0x7FF0000000000000L) >>> 52; // mask significand bits and shift up long significand = bitValue & 0x000FFFFFFFFFFFFFL; @@ -542,7 +542,7 @@ internal static string DoubleToHexStr(double value, NumberFormatInfo info, bool // them while ((significand != 0) && ((significand & 0xF) == 0)) { - significand = significand.TripleShift(4); + significand >>>= 4; fractionDigits--; } string hexSignificand = significand.ToString(upperCase ? "X" : "x", info); @@ -569,7 +569,7 @@ internal static string DoubleToHexStr(double value, NumberFormatInfo info, bool // them while ((significand != 0) && ((significand & 0xF) == 0)) { - significand = significand.TripleShift(4); + significand >>>= 4; fractionDigits--; } string hexSignificand = significand.ToString(upperCase ? "X" : "x", info); @@ -913,7 +913,7 @@ internal static string SingleToHexStr(float value, NumberFormatInfo info, bool u bool negative = (bitValue & 0x80000000) != 0; // mask exponent bits and shift down - int exponent = (bitValue & 0x7f800000).TripleShift(23); + int exponent = (bitValue & 0x7f800000) >>> 23; // mask significand bits and shift up // significand is 23-bits, so we shift to treat it like 24-bits int significand = (bitValue & 0x007FFFFF) << 1; @@ -942,8 +942,7 @@ internal static string SingleToHexStr(float value, NumberFormatInfo info, bool u // them while ((significand != 0) && ((significand & 0xF) == 0)) { - //significand >>>= 4; - significand = significand.TripleShift(4); + significand >>>= 4; fractionDigits--; } string hexSignificand = significand.ToString(upperCase ? "X" : "x", info); @@ -970,8 +969,7 @@ internal static string SingleToHexStr(float value, NumberFormatInfo info, bool u // them while ((significand != 0) && ((significand & 0xF) == 0)) { - //significand >>>= 4; - significand = significand.TripleShift(4); + significand >>>= 4; fractionDigits--; } string hexSignificand = significand.ToString(upperCase ? "X" : "x", info); @@ -3228,4 +3226,3 @@ private static uint ExtractFractionAndBiasedExponent(float value, out int expone } } } - diff --git a/src/J2N/Numerics/Double.cs b/src/J2N/Numerics/Double.cs index 33854496..e216d90f 100644 --- a/src/J2N/Numerics/Double.cs +++ b/src/J2N/Numerics/Double.cs @@ -465,7 +465,7 @@ public override bool Equals(object? obj) public override int GetHashCode() { long v = BitConversion.DoubleToInt64Bits(value); - return (int)(v ^ (v.TripleShift(32))); + return (int)(v ^ (v >>> 32)); } #endregion GetHashCode diff --git a/src/J2N/Numerics/Int64.cs b/src/J2N/Numerics/Int64.cs index 6aaad89b..8ee37da8 100644 --- a/src/J2N/Numerics/Int64.cs +++ b/src/J2N/Numerics/Int64.cs @@ -454,7 +454,7 @@ public override bool Equals(object? obj) /// A 32-bit signed integer hash code. public override int GetHashCode() { - return (int)(value ^ (value.TripleShift(32))); + return (int)(value ^ (value >>> 32)); } #endregion GetHashCode diff --git a/src/J2N/Numerics/RyuDouble.cs b/src/J2N/Numerics/RyuDouble.cs index 0eb6eb94..7b76f9bb 100644 --- a/src/J2N/Numerics/RyuDouble.cs +++ b/src/J2N/Numerics/RyuDouble.cs @@ -899,7 +899,7 @@ public static string ToString(double value, NumberFormatInfo info, RoundingMode if (bits == unchecked((long)0x8000000000000000L)) return string.Concat(info.NegativeSign, "0", info.NumberDecimalSeparator, "0"); // Otherwise extract the mantissa and exponent bits and run the full algorithm. - int ieeeExponent = (int)((bits.TripleShift(DOUBLE_MANTISSA_BITS)) & DOUBLE_EXPONENT_MASK); + int ieeeExponent = (int)((bits >>> DOUBLE_MANTISSA_BITS) & DOUBLE_EXPONENT_MASK); long ieeeMantissa = bits & DOUBLE_MANTISSA_MASK; int e2; long m2; @@ -971,7 +971,7 @@ public static string ToString(double value, NumberFormatInfo info, RoundingMode bool dmIsTrailingZeros = false, dvIsTrailingZeros = false; if (e2 >= 0) { - int q = Math.Max(0, (e2 * 78913).TripleShift(18) - 1); + int q = Math.Max(0, ((e2 * 78913) >>> 18) - 1); // k = constant + floor(log_2(5^q)) int k = POW5_INV_BITCOUNT + Pow5bits(q) - 1; int i = -e2 + q + k; @@ -1018,7 +1018,7 @@ public static string ToString(double value, NumberFormatInfo info, RoundingMode } else { - int q = Math.Max(0, ((-e2 * 732923).TripleShift(20)) - 1); + int q = Math.Max(0, ((-e2 * 732923) >>> 20) - 1); int i = -e2 - q; int k = Pow5bits(i) - POW5_BITCOUNT; int j = q - k; @@ -1304,7 +1304,7 @@ private unsafe static void WriteBuffer(char* result, ref int index, long output, [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int Pow5bits(int e) { - return ((e * 1217359).TripleShift(19)) + 1; + return ((e * 1217359) >>> 19) + 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] // J2N: Only called in one place @@ -1367,7 +1367,7 @@ private static int Pow5Factor(long value) private static long MulPow5divPow2(long m, int i, int j) { // m has at most 55 bits. - long mHigh = m.TripleShift(31); + long mHigh = m >>> 31; long mLow = m & 0x7fffffff; long bits13 = mHigh * POW5_SPLIT[i][0]; // 124 long bits03 = mLow * POW5_SPLIT[i][0]; // 93 @@ -1383,10 +1383,10 @@ private static long MulPow5divPow2(long m, int i, int j) throw new ArgumentException("" + actualShift); } return (((((( - ((bits00.TripleShift(31)) + bits01 + bits10).TripleShift(31)) - + bits02 + bits11).TripleShift(31)) - + bits03 + bits12).TripleShift(21)) - + (bits13 << 10)).TripleShift(actualShift); + ((bits00 >>> 31) + bits01 + bits10) >>> 31) + + bits02 + bits11) >>> 31) + + bits03 + bits12) >>> 21) + + (bits13 << 10)) >>> actualShift; } /// @@ -1396,7 +1396,7 @@ private static long MulPow5divPow2(long m, int i, int j) private static long MulPow5InvDivPow2(long m, int i, int j) { // m has at most 55 bits. - long mHigh = m.TripleShift(31); + long mHigh = m >>> 31; long mLow = m & 0x7fffffff; long bits13 = mHigh * POW5_INV_SPLIT[i][0]; long bits03 = mLow * POW5_INV_SPLIT[i][0]; @@ -1413,10 +1413,10 @@ private static long MulPow5InvDivPow2(long m, int i, int j) throw new ArgumentException("" + actualShift); } return (((((( - ((bits00.TripleShift(31)) + bits01 + bits10).TripleShift(31)) - + bits02 + bits11).TripleShift(31)) - + bits03 + bits12).TripleShift(21)) - + (bits13 << 10)).TripleShift(actualShift); + ((bits00 >>> 31) + bits01 + bits10) >>> 31) + + bits02 + bits11) >>> 31) + + bits03 + bits12) >>> 21) + + (bits13 << 10)) >>> actualShift; } } } diff --git a/src/J2N/Randomizer.cs b/src/J2N/Randomizer.cs index 793293ab..5f484bbe 100644 --- a/src/J2N/Randomizer.cs +++ b/src/J2N/Randomizer.cs @@ -16,11 +16,9 @@ */ #endregion -using J2N.Numerics; using System; using SR2 = J2N.Resources.Strings; - namespace J2N { /// @@ -135,7 +133,7 @@ protected virtual int NextInt(int bits) lock (syncRoot) { internalSeed = (internalSeed * multiplier + 0xbL) & ((1L << 48) - 1); - return (int)(internalSeed.TripleShift(48 - bits)); + return (int)(internalSeed >>> (48 - bits)); } } diff --git a/tests/J2N.Tests/Numerics/JDK8/FDBigInteger.cs b/tests/J2N.Tests/Numerics/JDK8/FDBigInteger.cs index 9d0c1919..994ded77 100644 --- a/tests/J2N.Tests/Numerics/JDK8/FDBigInteger.cs +++ b/tests/J2N.Tests/Numerics/JDK8/FDBigInteger.cs @@ -176,7 +176,7 @@ public FDBigInteger(long lValue, char[] digits, int kDigits, int nDigits) int n = Math.Max((nDigits + 8) / 9, 2); // estimate size needed. data = new int[n]; // allocate enough space data[0] = (int)lValue; // starting value - data[1] = (int)(lValue.TripleShift(32)); + data[1] = (int)(lValue >>> 32); offset = 0; nWords = 2; int i = kDigits; @@ -240,7 +240,7 @@ public static FDBigInteger ValueOfPow52(int p5, int p2) { return new FDBigInteger(new int[]{ pow5 << bitcount, - pow5.TripleShift(32 - bitcount) + pow5 >>> (32 - bitcount) }, wordcount); } } @@ -274,7 +274,7 @@ public static FDBigInteger ValueOfMulPow52(long value, int p5, int p2) Debug.Assert(p5 >= 0, p5.ToString()); Debug.Assert(p2 >= 0, p2.ToString()); int v0 = (int)value; - int v1 = (int)(value.TripleShift(32)); + int v1 = (int)(value >>> 32); int wordcount = p2 >> 5; int bitcount = p2 & 0x1f; if (p5 != 0) @@ -284,11 +284,10 @@ public static FDBigInteger ValueOfMulPow52(long value, int p5, int p2) long pow5 = SMALL_5_POW[p5] & LONG_MASK; long carry = (v0 & LONG_MASK) * pow5; v0 = (int)carry; - //carry >>>= 32; - carry = carry.TripleShift(32); + carry >>>= 32; carry = (v1 & LONG_MASK) * pow5 + carry; v1 = (int)carry; - int v2 = (int)(carry.TripleShift(32)); + int v2 = (int)(carry >>> 32); if (bitcount == 0) { return new FDBigInteger(new int[] { v0, v1, v2 }, wordcount); @@ -297,9 +296,9 @@ public static FDBigInteger ValueOfMulPow52(long value, int p5, int p2) { return new FDBigInteger(new int[]{ v0 << bitcount, - (v1 << bitcount) | (v0.TripleShift(32 - bitcount)), - (v2 << bitcount) | (v1.TripleShift(32 - bitcount)), - v2.TripleShift(32 - bitcount) + (v1 << bitcount) | (v0 >>> (32 - bitcount)), + (v2 << bitcount) | (v1 >>> (32 - bitcount)), + v2 >>> (32 - bitcount) }, wordcount); } } @@ -330,8 +329,8 @@ public static FDBigInteger ValueOfMulPow52(long value, int p5, int p2) { return new FDBigInteger(new int[]{ v0 << bitcount, - (v1 << bitcount) | (v0.TripleShift(32 - bitcount)), - v1.TripleShift(32 - bitcount) + (v1 << bitcount) | (v0 >>> (32 - bitcount)), + v1 >>> (32 - bitcount) }, wordcount); } } @@ -431,7 +430,7 @@ private static void LeftShift(int[] src, int idx, int[] result, int bitcount, in { int v2 = (prev << bitcount); prev = src[idx - 1]; - v2 |= (prev.TripleShift(anticount)); + v2 |= (prev >>> anticount); result[idx] = v2; } int v = prev << bitcount; @@ -483,7 +482,7 @@ public FDBigInteger LeftShift(int shift) // J2N TODO: Make into operator ? int anticount = 32 - bitcount; int idx = nWords - 1; int prev = data[idx]; - int hi = prev.TripleShift(anticount); + int hi = prev >>> anticount; int[] result; if (hi != 0) { @@ -509,12 +508,12 @@ public FDBigInteger LeftShift(int shift) // J2N TODO: Make into operator ? int prev = data[idx]; for (; idx < nWords - 1; idx++) { - int v2 = (prev.TripleShift(anticount)); + int v2 = (prev >>> anticount); prev = data[idx + 1]; v2 |= (prev << bitcount); data[idx] = v2; } - int v = prev.TripleShift(anticount); + int v = prev >>> anticount; data[idx] = v; if (v == 0) { @@ -526,7 +525,7 @@ public FDBigInteger LeftShift(int shift) // J2N TODO: Make into operator ? { int idx = nWords - 1; int prev = data[idx]; - int hi = prev.TripleShift(anticount); + int hi = prev >>> anticount; int[] result = data; int[] src = data; if (hi != 0) @@ -642,8 +641,7 @@ public int QuoRemIteration(FDBigInteger S) { sum += (td[tIndex] & LONG_MASK) + (sd[sIndex] & LONG_MASK); td[tIndex] = (int)sum; - //sum >>>= 32; // Signed or unsigned, answer is 0 or 1 - sum = sum.TripleShift(32); // Signed or unsigned, answer is 0 or 1 + sum >>>= 32; // Signed or unsigned, answer is 0 or 1 } // // Originally the following line read @@ -811,8 +809,7 @@ private static void Mult(int[] s1, int s1Len, int[] s2, int s2Len, int[] dst) { p += (dst[i + j] & LONG_MASK) + v * (s2[j] & LONG_MASK); dst[i + j] = (int)p; - //p >>>= 32; - p = p.TripleShift(32); + p >>>= 32; } dst[i + s2Len] = (int)p; } @@ -1168,9 +1165,9 @@ public FDBigInteger RightInplaceSub(FDBigInteger subtrahend) { top += (small.data[small.nWords - 1] & LONG_MASK); } - if ((top.TripleShift(32)) == 0) + if ((top >>> 32) == 0) { - if (((top + 1).TripleShift(32)) == 0) + if (((top + 1) >>> 32) == 0) { // good case - no carry extension if (bSize < thSize) @@ -1196,8 +1193,7 @@ public FDBigInteger RightInplaceSub(FDBigInteger subtrahend) return -1; } // here sum.nWords == this.nWords - //top >>>= 32; - top = top.TripleShift(32); + top >>>= 32; long v = (this.data[this.nWords - 1] & LONG_MASK); if (v < top) { @@ -1372,14 +1368,12 @@ private FDBigInteger Add(FDBigInteger other) // unroll 0th iteration, doing addition. long p = v * (data[0] & LONG_MASK) + (addend & LONG_MASK); data[0] = (int)p; - //p >>>= 32; - p = p.TripleShift(32); + p >>>= 32; for (int i = 1; i < nWords; i++) { p += v * (data[i] & LONG_MASK); data[i] = (int)p; - //p >>>= 32; - p = p.TripleShift(32); + p >>>= 32; } if (p != 0L) { @@ -1496,7 +1490,7 @@ private static int MultAndCarryBy10(int[] src, int srcLen, int[] dst) { long product = (src[i] & LONG_MASK) * 10L + carry; dst[i] = (int)product; - carry = product.TripleShift(32); + carry = product >>> 32; } return (int)carry; } @@ -1523,7 +1517,7 @@ private static void Mult(int[] src, int srcLen, int value, int[] dst) { long product = (src[i] & LONG_MASK) * val + carry; dst[i] = (int)product; - carry = product.TripleShift(32); + carry = product >>> 32; } dst[srcLen] = (int)carry; } @@ -1552,7 +1546,7 @@ private static void Mult(int[] src, int srcLen, int v0, int v1, int[] dst) { long product = v * (src[j] & LONG_MASK) + carry; dst[j] = (int)product; - carry = product.TripleShift(32); + carry = product >>> 32; } dst[srcLen] = (int)carry; v = v1 & LONG_MASK; @@ -1561,7 +1555,7 @@ private static void Mult(int[] src, int srcLen, int v0, int v1, int[] dst) { long product = (dst[j + 1] & LONG_MASK) + v * (src[j] & LONG_MASK) + carry; dst[j + 1] = (int)product; - carry = product.TripleShift(32); + carry = product >>> 32; } dst[srcLen + 1] = (int)carry; } diff --git a/tests/J2N.Tests/Numerics/JDK8/FloatingDecimal.cs b/tests/J2N.Tests/Numerics/JDK8/FloatingDecimal.cs index 20b75643..f9247f0c 100644 --- a/tests/J2N.Tests/Numerics/JDK8/FloatingDecimal.cs +++ b/tests/J2N.Tests/Numerics/JDK8/FloatingDecimal.cs @@ -675,8 +675,7 @@ internal void Dtoa(int binExp, long fractBits, int nSignificantBits, bool isComp } else { - //fractBits >>>= (EXP_SHIFT - binExp); - fractBits = fractBits.TripleShift(EXP_SHIFT - binExp); + fractBits >>>= (EXP_SHIFT - binExp); } DevelopLongDigits(0, fractBits, insignificant); return; @@ -739,8 +738,7 @@ internal void Dtoa(int binExp, long fractBits, int nSignificantBits, bool isComp // FDBigInteger. The resulting whole number will be // d * 2^(nFractBits-1-binExp). // - //fractBits >>>= tailZeros; - fractBits = fractBits.TripleShift(tailZeros); + fractBits >>>= tailZeros; B2 -= nFractBits - 1; int common2factor = Math.Min(B2, S2); B2 -= common2factor; @@ -1578,7 +1576,7 @@ public virtual double ToDouble() while (true) { // here ieeeBits can't be NaN, Infinity or zero - int binexp = (int)(ieeeBits.TripleShift(EXP_SHIFT)); + int binexp = (int)(ieeeBits >>> EXP_SHIFT); long bigBbits = ieeeBits & DoubleConsts.SIGNIF_BIT_MASK; if (binexp > 0) { @@ -1594,8 +1592,7 @@ public virtual double ToDouble() } binexp -= DoubleConsts.EXP_BIAS; int lowOrderZeros = bigBbits.TrailingZeroCount(); - //bigBbits >>>= lowOrderZeros; - bigBbits = bigBbits.TripleShift(lowOrderZeros); + bigBbits >>>= lowOrderZeros; int bigIntExp = binexp - EXP_SHIFT + lowOrderZeros; int bigIntNBits = EXP_SHIFT + 1 - lowOrderZeros; @@ -1939,7 +1936,7 @@ public virtual float ToSingle() while (true) { // here ieeeBits can't be NaN, Infinity or zero - int binexp = ieeeBits.TripleShift(SINGLE_EXP_SHIFT); + int binexp = ieeeBits >>> SINGLE_EXP_SHIFT; int bigBbits = ieeeBits & FloatConsts.SIGNIF_BIT_MASK; if (binexp > 0) { @@ -1955,8 +1952,7 @@ public virtual float ToSingle() } binexp -= FloatConsts.EXP_BIAS; int lowOrderZeros = bigBbits.TrailingZeroCount(); - //bigBbits >>>= lowOrderZeros; - bigBbits = bigBbits.TripleShift(lowOrderZeros); + bigBbits >>>= lowOrderZeros; int bigIntExp = binexp - SINGLE_EXP_SHIFT + lowOrderZeros; int bigIntNBits = SINGLE_EXP_SHIFT + 1 - lowOrderZeros; @@ -2893,7 +2889,7 @@ internal static IASCIIToBinaryConverter ParseHexString(string s) { int threshShift = DoubleConsts.SIGNIFICAND_WIDTH - FloatConsts.SIGNIFICAND_WIDTH - 1; bool floatSticky = (significand & ((1L << threshShift) - 1)) != 0 || round || sticky; - int iValue = (int)(significand.TripleShift(threshShift)); + int iValue = (int)(significand >>> threshShift); if ((iValue & 3) != 1 || floatSticky) { iValue++; @@ -2914,7 +2910,7 @@ internal static IASCIIToBinaryConverter ParseHexString(string s) Debug.Assert(threshShift >= DoubleConsts.SIGNIFICAND_WIDTH - FloatConsts.SIGNIFICAND_WIDTH); Debug.Assert(threshShift < DoubleConsts.SIGNIFICAND_WIDTH); bool floatSticky = (significand & ((1L << threshShift) - 1)) != 0 || round || sticky; - int iValue = (int)(significand.TripleShift(threshShift)); + int iValue = (int)(significand >>> threshShift); if ((iValue & 3) != 1 || floatSticky) { iValue++; diff --git a/tests/J2N.Tests/Numerics/JDK8/OldFDBigIntForTest.cs b/tests/J2N.Tests/Numerics/JDK8/OldFDBigIntForTest.cs index cdf04aeb..1b5b4f03 100644 --- a/tests/J2N.Tests/Numerics/JDK8/OldFDBigIntForTest.cs +++ b/tests/J2N.Tests/Numerics/JDK8/OldFDBigIntForTest.cs @@ -48,7 +48,7 @@ public OldFDBigIntForTest(long v) { data = new int[2]; data[0] = (int)v; - data[1] = (int)(v.TripleShift(32)); + data[1] = (int)(v >>> 32); nWords = (data[1] == 0) ? 1 : 2; } @@ -70,7 +70,7 @@ public OldFDBigIntForTest(long seed, char[] digit, int nd0, int nd) if (n < 2) n = 2; data = new int[n]; // allocate enough space data[0] = (int)seed; // starting value - data[1] = (int)(seed.TripleShift(32)); + data[1] = (int)(seed >>> 32); nWords = (data[1] == 0) ? 1 : 2; int i = nd0; int limit = nd - 5; // slurp digits 5 at a time. @@ -131,10 +131,10 @@ public void lshiftMe(int c) } else { - t[target--] = s[src].TripleShift(anticount); + t[target--] = s[src] >>> anticount; while (src >= 1) { - t[target--] = (s[src] << bitcount) | (s[--src].TripleShift(anticount)); + t[target--] = (s[src] << bitcount) | (s[--src] >>> anticount); } t[target--] = s[src] << bitcount; } @@ -193,8 +193,7 @@ public int normalizeMe() // will have to shift up into the next word. // too bad. for (bitcount = 32; (v & 0xf0000000) != 0; bitcount--) - //v >>>= 1; - v = v.TripleShift(1); + v >>>= 1; } else { @@ -233,8 +232,7 @@ public OldFDBigIntForTest { p += v * ((long)data[i] & 0xffffffffL); r[i] = (int)p; - //p >>>= 32; - p = p.TripleShift(32); + p >>>= 32; } if (p == 0L) { @@ -260,14 +258,12 @@ public void multaddMe(int iv, int addend) // unroll 0th iteration, doing addition. p = v * ((long)data[0] & 0xffffffffL) + ((long)addend & 0xffffffffL); data[0] = (int)p; - //p >>>= 32; - p = p.TripleShift(32); + p >>>= 32; for (int i = 1; i < nWords; i++) { p += v * ((long)data[i] & 0xffffffffL); data[i] = (int)p; - //p >>>= 32; - p = p.TripleShift(32); + p >>>= 32; } if (p != 0L) { @@ -296,8 +292,7 @@ public OldFDBigIntForTest mult(OldFDBigIntForTest other) { p += ((long)r[i + j] & 0xffffffffL) + v * ((long)other.data[j] & 0xffffffffL); // UNSIGNED CONVERSIONS ALL 'ROUND. r[i + j] = (int)p; - //p >>>= 32; - p = p.TripleShift(32); + p >>>= 32; } r[i + j] = (int)p; } @@ -501,8 +496,7 @@ public int quoRemIteration(OldFDBigIntForTest S) { sum += ((long)data[i] & 0xffffffffL) + ((long)S.data[i] & 0xffffffffL); data[i] = (int)sum; - //sum >>= 32; // Signed or unsigned, answer is 0 or 1 - sum = sum.TripleShift(32); + sum >>>= 32; // Signed or unsigned, answer is 0 or 1 } /* * Originally the following line read diff --git a/tests/J2N.Tests/Numerics/JDK8/OldFloatingDecimalForTest.cs b/tests/J2N.Tests/Numerics/JDK8/OldFloatingDecimalForTest.cs index 2a23a122..60e35594 100644 --- a/tests/J2N.Tests/Numerics/JDK8/OldFloatingDecimalForTest.cs +++ b/tests/J2N.Tests/Numerics/JDK8/OldFloatingDecimalForTest.cs @@ -244,7 +244,7 @@ private static OldFDBigIntForTest constructPow52(int p5, int p2) private OldFDBigIntForTest doubleToBigInt(double dval) { long lbits = BitConversion.DoubleToInt64Bits(dval) & ~signMask; - int binexp = (int)(lbits.TripleShift(expShift)); + int binexp = (int)(lbits >>> expShift); lbits &= fractMask; if (binexp > 0) { @@ -267,8 +267,7 @@ private OldFDBigIntForTest doubleToBigInt(double dval) * and we know how many there are. */ int lowOrderZeros = expShift + 1 - nbits; - //lbits >>>= lowOrderZeros; - lbits = lbits.TripleShift(lowOrderZeros); + lbits >>>= lowOrderZeros; bigIntExp = binexp + 1 - nbits; bigIntNBits = nbits; @@ -284,7 +283,7 @@ private OldFDBigIntForTest doubleToBigInt(double dval) private static double ulp(double dval, bool subtracting) { long lbits = BitConversion.DoubleToInt64Bits(dval) & ~signMask; - int binexp = (int)(lbits.TripleShift(expShift)); + int binexp = (int)(lbits >>> expShift); double ulpval; if (subtracting && (binexp >= expShift) && ((lbits & fractMask) == 0L)) { @@ -661,7 +660,7 @@ private void dtoa(int binExp, long fractBits, int nSignificantBits) } else { - fractBits = fractBits.TripleShift(expShift - binExp); + fractBits >>>= (expShift - binExp); } developLongDigits(0, fractBits, halfULP); return; @@ -743,7 +742,7 @@ private void dtoa(int binExp, long fractBits, int nSignificantBits) * OldFDBigIntForTest. The resulting whole number will be * d * 2^(nFractBits-1-binExp). */ - fractBits = fractBits.TripleShift(expShift + 1 - nFractBits); + fractBits >>>= (expShift + 1 - nFractBits); B2 -= nFractBits - 1; int common2factor = Math.Min(B2, S2); B2 -= common2factor; diff --git a/tests/J2N.Tests/Numerics/Ryu/SlowConversion.cs b/tests/J2N.Tests/Numerics/Ryu/SlowConversion.cs index f6972a3a..11ee3662 100644 --- a/tests/J2N.Tests/Numerics/Ryu/SlowConversion.cs +++ b/tests/J2N.Tests/Numerics/Ryu/SlowConversion.cs @@ -82,9 +82,9 @@ internal static string asString(long bits, FloatingPointFormat format, RoundingM int mantissaBits = format.MantissaBits; int exponentBits = format.ExponentBits; - int ieeeExponent = (int)((bits.TripleShift(mantissaBits)) & ((1 << exponentBits) - 1)); + int ieeeExponent = (int)((bits >>> mantissaBits) & ((1 << exponentBits) - 1)); long ieeeMantissa = bits & ((1L << mantissaBits) - 1); - bool sign = ((bits.TripleShift(mantissaBits + exponentBits)) & 1) != 0; + bool sign = ((bits >>> (mantissaBits + exponentBits)) & 1) != 0; bool even = (bits & 1) == 0; // Exit early if it's NaN, Infinity, or 0. diff --git a/tests/J2N.Tests/Numerics/TestInt64.cs b/tests/J2N.Tests/Numerics/TestInt64.cs index 8580406a..b6688b20 100644 --- a/tests/J2N.Tests/Numerics/TestInt64.cs +++ b/tests/J2N.Tests/Numerics/TestInt64.cs @@ -661,10 +661,10 @@ public void GetTypeCode_Invoke_ReturnsInt64() [Test] public void Test_hashCode() { - assertEquals((int)(1L ^ (1L.TripleShift(32))), new Int64(1).GetHashCode()); - assertEquals((int)(2L ^ (2L.TripleShift(32))), new Int64(2).GetHashCode()); - assertEquals((int)(0L ^ (0L.TripleShift(32))), new Int64(0).GetHashCode()); - assertEquals((int)(-1L ^ ((-1L).TripleShift(32))), new Int64(-1).GetHashCode()); + assertEquals((int)(1L ^ (1L >>> 32)), new Int64(1).GetHashCode()); + assertEquals((int)(2L ^ (2L >>> 32)), new Int64(2).GetHashCode()); + assertEquals((int)(0L ^ (0L >>> 32)), new Int64(0).GetHashCode()); + assertEquals(unchecked((int)(-1L ^ (-1L >>> 32))), new Int64(-1).GetHashCode()); } // J2N: Removed this overload because all of the constructors are deprecated in JDK 16