// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; using System.Runtime.CompilerServices; namespace SixLabors.PolygonClipper { /// /// Provides extension methods for floating-point numbers. /// internal static class FloatExtensions { /// /// Returns the next representable double value in the direction of y. /// /// /// The starting floating-point number. /// The target floating-point number. /// The next representable value of x towards y. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double NextAfter(this double x, double y) { // Special cases if (double.IsNaN(x) || double.IsNaN(y)) { return double.NaN; } if (x == y) { return y; } if (double.IsPositiveInfinity(x)) { return double.PositiveInfinity; } if (double.IsNegativeInfinity(x)) { return double.NegativeInfinity; } // Handle stepping from zero if (x == 0D) { return Math.CopySign(double.Epsilon, y); // Smallest positive subnormal double } // Convert double to raw bits long bits = BitConverter.DoubleToInt64Bits(x); // Adjust bits to get the next representable value // Moving in the same sign direction if ((y > x) == (x > 0D)) { bits++; } else { bits--; } // Convert bits back to double double next = BitConverter.Int64BitsToDouble(bits); // Ensure correct handling of signed zeros if (next == 0D) { return Math.CopySign(next, x); } return next; } } }