未验证 提交 c8cc6c14 编写于 作者: H Huo Yaoyuan 提交者: GitHub

Redo minor cleanups in System.Runtime.Numerics (#71274)

* Replace union with BitConverter

* Cleanup complex

* Use HashCode

* Update src/libraries/System.Runtime.Numerics/src/System/Numerics/NumericsHelpers.cs

* Update src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Co-authored-by: NTanner Gooding <tagoo@outlook.com>
Co-authored-by: NStephen Toub <stoub@microsoft.com>
Co-authored-by: NTanner Gooding <tagoo@outlook.com>
上级 f1731426
......@@ -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)
......
......@@ -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}>";
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册