34 lines
1.2 KiB
C#
34 lines
1.2 KiB
C#
namespace PersistentOrderedMap;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
public struct DoubleStrategy : IKeyStrategy<double>
|
|
{
|
|
public bool IsLossless => true;
|
|
// Use the standard comparison for the fallback/refine step
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public int Compare(double x, double y) => x.CompareTo(y);
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public long GetPrefix(double key)
|
|
{
|
|
// 1. Bit Cast to Long (0 cost)
|
|
long bits = Unsafe.As<double, long>(ref key);
|
|
|
|
// 2. The Magic Twist
|
|
// If the sign bit (MSB) is set (negative), we flip ALL bits.
|
|
// If the sign bit is clear (positive), we flip ONLY the sign bit.
|
|
// This maps:
|
|
// -Negative Max -> 0
|
|
// -0 -> Midpoint
|
|
// +Negative Max -> Max
|
|
|
|
long mask = (bits >> 63); // 0 for positive, -1 (All 1s) for negative
|
|
|
|
// If negative: bits ^ -1 = ~bits (Flip All)
|
|
// If positive: bits ^ 0 = bits (Flip None)
|
|
// Then we toggle the sign bit (0x8000...) to shift the range to signed long.
|
|
|
|
return (bits ^ (mask & 0x7FFFFFFFFFFFFFFF)) ^ unchecked((long)0x8000000000000000);
|
|
}
|
|
}
|
|
|