diff --git a/src/BLite.Core/Indexing/IndexKey.cs b/src/BLite.Core/Indexing/IndexKey.cs
index a36926c0..282dde9e 100644
--- a/src/BLite.Core/Indexing/IndexKey.cs
+++ b/src/BLite.Core/Indexing/IndexKey.cs
@@ -99,7 +99,13 @@ public IndexKey(double value)
// Result: lexicographic byte order == IEEE 754 numeric order for all finite and ±Inf.
// -0.0 == +0.0, so both take the key of +0.0; -0.0 would otherwise encode just below it (#249).
if (value == 0) value = 0.0;
- var bits = BitConverter.DoubleToInt64Bits(value);
+ // A NaN's sign bit and payload are arbitrary (a computed NaN has the sign bit clear on Arm64,
+ // set on x64), which put NaNs both below -Inf and above +Inf. Every NaN takes one key, that of
+ // the bits of double.NaN (0xFFF8...), which sorts below -Inf, where double.CompareTo orders
+ // NaN (#257). The bits are spelled out so the key does not depend on how a NaN was produced.
+ var bits = double.IsNaN(value)
+ ? unchecked((long)0xFFF8_0000_0000_0000UL)
+ : BitConverter.DoubleToInt64Bits(value);
ulong u = bits < 0 ? ~(ulong)bits : (ulong)bits | 0x8000_0000_0000_0000UL;
_data = [KeyPrefix, (byte)(u >> 56), (byte)(u >> 48), (byte)(u >> 40), (byte)(u >> 32),
(byte)(u >> 24), (byte)(u >> 16), (byte)(u >> 8), (byte)u];
diff --git a/tests/BLite.Tests/IndexKeyNaNTests.cs b/tests/BLite.Tests/IndexKeyNaNTests.cs
new file mode 100644
index 00000000..300500df
--- /dev/null
+++ b/tests/BLite.Tests/IndexKeyNaNTests.cs
@@ -0,0 +1,73 @@
+using BLite.Core.Indexing;
+using BLite.Core.Storage;
+
+namespace BLite.Tests;
+
+///
+/// Every NaN gets one index key, below -Infinity (#257). The sort-preserving double encoding keyed a
+/// NaN by its bits, so a NaN with the sign bit clear (what Arm64 computes for 0.0 / 0.0) sorted above
+/// +Infinity and one with the sign bit set (, what x64 computes) below
+/// -Infinity: the order of an index-served query depended on the CPU that wrote the value.
+///
+public sealed class IndexKeyNaNTests : IDisposable
+{
+ private static readonly double PositiveNaN = BitConverter.Int64BitsToDouble(0x7FF8_0000_0000_0000L);
+ private static readonly double PayloadNaN = BitConverter.Int64BitsToDouble(0x7FF0_0000_0000_0001L);
+ private static readonly double NegativePayloadNaN = BitConverter.Int64BitsToDouble(unchecked((long)0xFFF0_0000_0000_0001UL));
+
+ private readonly string _dbPath = Path.Combine(Path.GetTempPath(), $"blite_nan_{Guid.NewGuid():N}.db");
+
+ public void Dispose()
+ {
+ foreach (var p in new[] { _dbPath, Path.ChangeExtension(_dbPath, ".wal") })
+ try { if (File.Exists(p)) File.Delete(p); } catch { }
+ }
+
+ public static IEnumerable