Skip to content

Redo minor cleanups in System.Runtime.Numerics #71274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,23 +383,15 @@ 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)
{
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}>";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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)
{
Expand All @@ -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
Expand Down