Skip to content

Commit 3b9a695

Browse files
Merge pull request #9 from stefannikolei/sn/fix/issue96
Port GenericTests from Rust lib
2 parents ffdb3a5 + a02b3d7 commit 3b9a695

32 files changed

+747
-581
lines changed

src/PolygonClipper/FloatExtensions.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
7+
namespace PolygonClipper;
8+
9+
/// <summary>
10+
/// Provides extension methods for floating-point numbers.
11+
/// </summary>
12+
internal static class FloatExtensions
13+
{
14+
/// <summary>
15+
/// Returns the next representable double value in the direction of y.
16+
/// </summary>
17+
/// <remarks><see href="https://docs.rs/float_next_after/latest/src/float_next_after/lib.rs.html"/></remarks>
18+
/// <param name="x">The starting floating-point number.</param>
19+
/// <param name="y">The target floating-point number.</param>
20+
/// <returns>The next representable value of x towards y.</returns>
21+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
22+
public static double NextAfter(this double x, double y)
23+
{
24+
// Special cases
25+
if (double.IsNaN(x) || double.IsNaN(y))
26+
{
27+
return double.NaN;
28+
}
29+
30+
if (x == y)
31+
{
32+
return y;
33+
}
34+
35+
if (double.IsPositiveInfinity(x))
36+
{
37+
return double.PositiveInfinity;
38+
}
39+
40+
if (double.IsNegativeInfinity(x))
41+
{
42+
return double.NegativeInfinity;
43+
}
44+
45+
// Handle stepping from zero
46+
if (x == 0D)
47+
{
48+
return Math.CopySign(double.Epsilon, y); // Smallest positive subnormal double
49+
}
50+
51+
// Convert double to raw bits
52+
long bits = BitConverter.DoubleToInt64Bits(x);
53+
54+
// Adjust bits to get the next representable value
55+
if ((y > x) == (x > 0D)) // Moving in the same sign direction
56+
{
57+
bits++;
58+
}
59+
else
60+
{
61+
bits--;
62+
}
63+
64+
// Convert bits back to double
65+
double next = BitConverter.Int64BitsToDouble(bits);
66+
67+
// Ensure correct handling of signed zeros
68+
if (next == 0D)
69+
{
70+
return Math.CopySign(next, x);
71+
}
72+
73+
return next;
74+
}
75+
}

0 commit comments

Comments
 (0)