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
13 changes: 13 additions & 0 deletions PowerKit.Tests/Extensions/DoubleExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,17 @@ public void ParseOrDefault_Test()
double.ParseOrDefault("abc", -1.0).Should().Be(-1.0);
double.ParseOrDefault(null).Should().Be(0.0);
}

[Fact]
public void Wrap_Test()
{
// Act & assert
5.0.Wrap(0.0, 10.0).Should().Be(5.0);
13.0.Wrap(0.0, 10.0).Should().Be(3.0);
(-3.0).Wrap(0.0, 10.0).Should().Be(7.0);
Comment thread
Tyrrrz marked this conversation as resolved.
(-10.0).Wrap(0.0, 10.0).Should().Be(0.0);
0.0.Wrap(0.0, 10.0).Should().Be(0.0);
10.0.Wrap(0.0, 10.0).Should().Be(0.0);
23.0.Wrap(0.0, 10.0).Should().Be(3.0);
}
}
13 changes: 13 additions & 0 deletions PowerKit.Tests/Extensions/SingleExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,17 @@ public void ParseOrDefault_Test()
float.ParseOrDefault("abc", -1.0f).Should().Be(-1.0f);
float.ParseOrDefault(null).Should().Be(0.0f);
}

[Fact]
public void Wrap_Test()
{
// Act & assert
5.0f.Wrap(0.0f, 10.0f).Should().Be(5.0f);
13.0f.Wrap(0.0f, 10.0f).Should().Be(3.0f);
(-3.0f).Wrap(0.0f, 10.0f).Should().Be(7.0f);
Comment thread
Tyrrrz marked this conversation as resolved.
(-10.0f).Wrap(0.0f, 10.0f).Should().Be(0.0f);
0.0f.Wrap(0.0f, 10.0f).Should().Be(0.0f);
10.0f.Wrap(0.0f, 10.0f).Should().Be(0.0f);
23.0f.Wrap(0.0f, 10.0f).Should().Be(3.0f);
}
}
27 changes: 27 additions & 0 deletions PowerKit/Extensions/DoubleExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,31 @@ public static double ParseOrDefault(
public static double ParseOrDefault(string? str, double defaultValue = default) =>
double.ParseOrDefault(str, CultureInfo.CurrentCulture, defaultValue);
}

extension(double value)
{
/// <summary>
/// Wraps the value into the half-open range [<paramref name="min" />, <paramref name="max" />).
/// A value equal to <paramref name="max" /> wraps to <paramref name="min" />.
/// </summary>
/// <param name="min">The inclusive lower bound of the range.</param>
/// <param name="max">The exclusive upper bound of the range.</param>
/// <remarks>
/// This method requires <paramref name="max" /> to be greater than <paramref name="min" />.
/// If <paramref name="max" /> is less than or equal to <paramref name="min" />, the behavior is invalid.
/// </remarks>
public double Wrap(double min, double max)
{
if (max <= min)
{
throw new ArgumentOutOfRangeException(
nameof(max),
"The maximum value must be greater than the minimum value."
);
}

var range = max - min;
return min + (((value - min) % range + range) % range);
}
}
}
27 changes: 27 additions & 0 deletions PowerKit/Extensions/SingleExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,31 @@ public static float ParseOrDefault(
public static float ParseOrDefault(string? str, float defaultValue = default) =>
float.ParseOrDefault(str, CultureInfo.CurrentCulture, defaultValue);
}

extension(float value)
{
/// <summary>
/// Wraps the value into the half-open range [<paramref name="min" />, <paramref name="max" />),
/// cycling it back around when it exceeds the bounds.
/// </summary>
/// <remarks>
/// The returned value is greater than or equal to <paramref name="min" /> and less than
/// <paramref name="max" /> for valid ranges. A value equal to <paramref name="max" />
/// wraps to <paramref name="min" />.
/// When <paramref name="max" /> is less than or equal to <paramref name="min" />, this
/// method does not throw; it follows floating-point arithmetic and may return
/// <see cref="float.NaN" />.
/// </remarks>
public float Wrap(float min, float max)
{
if (max <= min)
{
throw new ArgumentOutOfRangeException(nameof(max), "max must be greater than min.");
}

var range = max - min;
var normalized = ((value - min) % range + range) % range;
return min + normalized;
}
}
}