diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs index 2a76c9ad7df7975dc5736e5611b949d3a9d80ed7..53b9782d1d5c3775ce9fefc486332359f33c2504 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs @@ -1084,12 +1084,10 @@ public override int GetHashCode() if (_bits is null) return _sign; - int hash = _sign; - for (int iv = _bits.Length; --iv >= 0;) - hash = unchecked((int)CombineHash((uint)hash, _bits[iv])); - return hash; - - static uint CombineHash(uint u1, uint u2) => ((u1 << 7) | (u1 >> 25)) ^ u2; + HashCode hash = default; + hash.AddBytes(MemoryMarshal.AsBytes(_bits.AsSpan())); + hash.Add(_sign); + return hash.ToHashCode(); } public override bool Equals([NotNullWhen(true)] object? obj) diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs index f0e69c365cf0e167be3dbfeeb46a31f743a61d1f..c2926e1c99e768666ce201b4ff2866cf3411317e 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs @@ -383,8 +383,7 @@ public static Complex Reciprocal(Complex value) public override bool Equals([NotNullWhen(true)] object? obj) { - if (!(obj is Complex)) return false; - return Equals((Complex)obj); + return obj is Complex other && Equals(other); } public bool Equals(Complex value) @@ -392,14 +391,7 @@ public bool Equals(Complex value) return m_real.Equals(value.m_real) && m_imaginary.Equals(value.m_imaginary); } - public override int GetHashCode() - { - int n1 = 99999997; - int realHash = m_real.GetHashCode() % n1; - int imaginaryHash = m_imaginary.GetHashCode(); - int finalHash = realHash ^ imaginaryHash; - return finalHash; - } + public override int GetHashCode() => HashCode.Combine(m_real, m_imaginary); public override string ToString() => $"<{m_real}; {m_imaginary}>"; diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/NumericsHelpers.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/NumericsHelpers.cs index ebee3f5bf16022a4d4327276d71b9116ffe55cac..797b848b496d5882068b69dc57394dca1e9df17d 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/NumericsHelpers.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/NumericsHelpers.cs @@ -2,32 +2,20 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Runtime.InteropServices; namespace System.Numerics { - [StructLayout(LayoutKind.Explicit)] - internal struct DoubleUlong - { - [FieldOffset(0)] - public double dbl; - [FieldOffset(0)] - public ulong uu; - } - internal static class NumericsHelpers { private const int kcbitUint = 32; public static void GetDoubleParts(double dbl, out int sign, out int exp, out ulong man, out bool fFinite) { - DoubleUlong du; - du.uu = 0; - du.dbl = dbl; + ulong bits = BitConverter.DoubleToUInt64Bits(dbl); - sign = 1 - ((int)(du.uu >> 62) & 2); - man = du.uu & 0x000FFFFFFFFFFFFF; - exp = (int)(du.uu >> 52) & 0x7FF; + sign = 1 - ((int)(bits >> 62) & 2); + man = bits & 0x000FFFFFFFFFFFFF; + exp = (int)(bits >> 52) & 0x7FF; if (exp == 0) { // Denormalized number. @@ -51,11 +39,12 @@ public static void GetDoubleParts(double dbl, out int sign, out int exp, out ulo public static double GetDoubleFromParts(int sign, int exp, ulong man) { - DoubleUlong du; - du.dbl = 0; + ulong bits; if (man == 0) - du.uu = 0; + { + bits = 0; + } else { // Normalize so that 0x0010 0000 0000 0000 is the highest bit set. @@ -74,7 +63,7 @@ public static double GetDoubleFromParts(int sign, int exp, ulong man) if (exp >= 0x7FF) { // Infinity. - du.uu = 0x7FF0000000000000; + bits = 0x7FF0000000000000; } else if (exp <= 0) { @@ -83,25 +72,25 @@ public static double GetDoubleFromParts(int sign, int exp, ulong man) if (exp < -52) { // Underflow to zero. - du.uu = 0; + bits = 0; } else { - du.uu = man >> -exp; - Debug.Assert(du.uu != 0); + bits = man >> -exp; + Debug.Assert(bits != 0); } } else { // Mask off the implicit high bit. - du.uu = (man & 0x000FFFFFFFFFFFFF) | ((ulong)exp << 52); + bits = (man & 0x000FFFFFFFFFFFFF) | ((ulong)exp << 52); } } if (sign < 0) - du.uu |= 0x8000000000000000; + bits |= 0x8000000000000000; - return du.dbl; + return BitConverter.UInt64BitsToDouble(bits); } // Do an in-place two's complement. "Dangerous" because it causes