// 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;
}
}
}