Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions src/PolygonClipper/FloatExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System;
using System.Runtime.CompilerServices;

namespace PolygonClipper;

/// <summary>
/// Provides extension methods for floating-point numbers.
/// </summary>
internal static class FloatExtensions
{
/// <summary>
/// Returns the next representable double value in the direction of y.
/// </summary>
/// <remarks><see href="https://docs.rs/float_next_after/latest/src/float_next_after/lib.rs.html"/></remarks>
/// <param name="x">The starting floating-point number.</param>
/// <param name="y">The target floating-point number.</param>
/// <returns>The next representable value of x towards y.</returns>
[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
if ((y > x) == (x > 0D)) // Moving in the same sign direction

Check warning on line 55 in src/PolygonClipper/FloatExtensions.cs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, net9.0, 9.0.x, true, -x64, false)

Check warning on line 55 in src/PolygonClipper/FloatExtensions.cs

View workflow job for this annotation

GitHub Actions / Build (ubuntu-latest, net8.0, 8.0.x, -x64, false)

Check warning on line 55 in src/PolygonClipper/FloatExtensions.cs

View workflow job for this annotation

GitHub Actions / Build (windows-latest, net9.0, 9.0.x, true, -x64, false)

Check warning on line 55 in src/PolygonClipper/FloatExtensions.cs

View workflow job for this annotation

GitHub Actions / Build (windows-latest, net8.0, 8.0.x, -x64, false)

{
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;
}
}
Loading
Loading