// 1.   ( +0)
uint64_t bad1 = 0x0000000000000001ULL;  //    double (~4.94e-324)

// 2.   
uint64_t bad2 = 0x0010000000000000ULL;  // ~2.225e-308

// 3.     (power of 2 boundary)
uint64_t bad3 = 0x3FF0000000000000ULL;  // 1.0 
uint64_t bad4 = 0x3FF0000000000001ULL;  // nextafter(1.0, +inf)

// 4.   90 ( )
uint64_t bad5 = 0x4059A00000000000ULL;  //  89.95
uint64_t bad6 = 0x4059B00000000000ULL;  //  

// 5.    90
uint64_t bad7 = 0x4059C00000000000ULL;  
uint64_t bad8 = 0x4059D00000000000ULL;


using System;

ulong[] badBits = new ulong[]
{
    // 1.    
    0x0000000000000001UL,

    // 2.      
    0x000FFFFFFFFFFFFFUL,

    // 3.    (2^-1022)
    0x0010000000000000UL,

    // 4.   ULP  1.0
    0x3FF0000000000000UL,  // 1.0
    0x3FF0000000000001UL,  // nextafter(1.0)

    // 5.    90 (   )
    0x4059A00000000000UL,  // ~89.95
    0x4059BFFFFFFFFFFFUL,  //     ULP
    0x4059C00000000000UL,

    // 6.       60 (  )
    0x404E000000000000UL,  // ~60
    0x404E000000000001UL
};


foreach (var bits in badBits)
{
    double phi = BitConverter.Int64BitsToDouble((long)bits);
    
    double s1 = MeridianArc(phi);
    double s2 = MeridianArc(Math.BitIncrement(phi));
  // C# 9+ : nextafter 
    
    if (s2 <= s1)
    {
        Console.WriteLine($"! phi = {phi} (bits = 0x{bits:X16})  s1={s1}  s2={s2}");
    }
}
