From 741b11c6d708a41b92fefbbe853d6d67227e7489 Mon Sep 17 00:00:00 2001 From: DomCR Date: Wed, 9 Sep 2026 07:31:54 +0200 Subject: [PATCH 1/9] Enhance angle normalization with 'absolute' parameter Added 'absolute' parameter to NormalizeAngle, NormalizeAngleRadians, and RadToDeg for flexible negative angle handling. Updated XML docs and extended unit tests to cover both absolute and non-absolute scenarios. --- CSMath.Tests/MathHelperTests.cs | 25 +++++++++++++++++++++++++ CSMath/MathHelper.cs | 15 +++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/CSMath.Tests/MathHelperTests.cs b/CSMath.Tests/MathHelperTests.cs index 8760293..e14bd28 100644 --- a/CSMath.Tests/MathHelperTests.cs +++ b/CSMath.Tests/MathHelperTests.cs @@ -195,6 +195,31 @@ public void NormalizeAngleTest(double number, double expected) Assert.Equal(expected, MathHelper.NormalizeAngle(number)); } + [Theory] + [InlineData(0.0, 0.0)] + [InlineData(180.0, 180.0)] + [InlineData(360.0, 360.0)] + [InlineData(-360.0, 360.0)] + [InlineData(720.0, 0.0)] + [InlineData(450.0, 90.0)] + [InlineData(-90.0, -90.0)] + [InlineData(-180.0, -180.0)] + [InlineData(-450.0, -90.0)] + [InlineData(-720.0, 0.0)] + public void NormalizeAngle_NotAbsolute_ReturnsExpected(double number, double expected) + { + Assert.Equal(expected, MathHelper.NormalizeAngle(number, false)); + } + + [Theory] + [InlineData(-90.0, 270.0)] + [InlineData(-450.0, 270.0)] + [InlineData(90.0, 90.0)] + public void NormalizeAngle_Absolute_ReturnsExpected(double number, double expected) + { + Assert.Equal(expected, MathHelper.NormalizeAngle(number, true)); + } + [Theory] [InlineData(0.0, 0.0)] [InlineData(MathHelper.HalfPI, 90.0)] diff --git a/CSMath/MathHelper.cs b/CSMath/MathHelper.cs index 980e5d0..7c47a02 100644 --- a/CSMath/MathHelper.cs +++ b/CSMath/MathHelper.cs @@ -297,9 +297,10 @@ public static bool IsZero(double number, double threshold) /// Normalizes the value of an angle in degrees between 0-360. /// /// Angle in degrees. + /// If true, negative angles will be converted to its positive equivalent. /// The equivalent angle in the range 0-360. /// Negative angles will be converted to its positive equivalent. - public static double NormalizeAngle(double angle) + public static double NormalizeAngle(double angle, bool absolute = true) { if (IsEqual(Math.Abs(angle), 360.0)) { @@ -312,7 +313,7 @@ public static double NormalizeAngle(double angle) return 0.0; } - if (normalized < 0) + if (normalized < 0 && absolute) { return 360.0 + normalized; } @@ -324,8 +325,9 @@ public static double NormalizeAngle(double angle) /// Normalizes the value of an angle in radians between 0-2π. /// /// Angle in radians. + /// If true, negative angles will be converted to its positive equivalent. /// The equivalent angle in the range 0-2π. - public static double NormalizeAngleRadians(double angle) + public static double NormalizeAngleRadians(double angle, bool absolute = true) { if (angle < 0.0 || angle > TwoPI) { @@ -339,12 +341,13 @@ public static double NormalizeAngleRadians(double angle) /// Convert a value from radian to degree. /// /// Value in radians - /// Calculates the negative values in a 0-360 range. + /// Normalizes the value to a 0-360 range. + /// If true, negative values will be converted to its positive equivalent. /// The degree value. - public static double RadToDeg(double value, bool absolute = true) + public static double RadToDeg(double value, bool normalize = true, bool absolute = true) { var result = value * RadToDegFactor; - return NormalizeAngle(result); + return normalize ? NormalizeAngle(result, absolute) : result; } /// From ac81b57e09aeb7795d134f1a3ccc0493d80e7f9c Mon Sep 17 00:00:00 2001 From: DomCR Date: Wed, 9 Sep 2026 07:40:59 +0200 Subject: [PATCH 2/9] Refactor angle normalization and expand unit tests Added and reorganized unit tests for `IsEqual`, `IsZero`, and angle normalization methods, covering custom thresholds and both absolute/non-absolute cases. Refactored `NormalizeAngleRadians` for improved handling of negative angles and multiples of `TwoPI`, and updated XML documentation. --- CSMath.Tests/MathHelperTests.cs | 76 +++++++++++++++++++++++---------- CSMath/MathHelper.cs | 18 ++++++-- 2 files changed, 68 insertions(+), 26 deletions(-) diff --git a/CSMath.Tests/MathHelperTests.cs b/CSMath.Tests/MathHelperTests.cs index e14bd28..51367b4 100644 --- a/CSMath.Tests/MathHelperTests.cs +++ b/CSMath.Tests/MathHelperTests.cs @@ -142,6 +142,14 @@ public void IsAlmostZero_ReturnsExpected(double value, bool expected) Assert.Equal(expected, MathHelper.IsAlmostZero(value)); } + [Theory] + [InlineData(1.0, 1.05, 0.1, true)] + [InlineData(1.0, 1.5, 0.1, false)] + public void IsEqual_CustomThreshold_ReturnsExpected(double a, double b, double threshold, bool expected) + { + Assert.Equal(expected, MathHelper.IsEqual(a, b, threshold)); + } + [Theory] [InlineData(1.0, 1.0000000000005, true)] [InlineData(5.0, 5.0, true)] @@ -153,11 +161,11 @@ public void IsEqual_ReturnsExpected(double a, double b, bool expected) } [Theory] - [InlineData(1.0, 1.05, 0.1, true)] - [InlineData(1.0, 1.5, 0.1, false)] - public void IsEqual_CustomThreshold_ReturnsExpected(double a, double b, double threshold, bool expected) + [InlineData(0.05, 0.1, true)] + [InlineData(0.2, 0.1, false)] + public void IsZero_CustomThreshold_ReturnsExpected(double value, double threshold, bool expected) { - Assert.Equal(expected, MathHelper.IsEqual(a, b, threshold)); + Assert.Equal(expected, MathHelper.IsZero(value, threshold)); } [Theory] @@ -174,25 +182,12 @@ public void IsZero_ReturnsExpected(double value, bool expected) } [Theory] - [InlineData(0.05, 0.1, true)] - [InlineData(0.2, 0.1, false)] - public void IsZero_CustomThreshold_ReturnsExpected(double value, double threshold, bool expected) - { - Assert.Equal(expected, MathHelper.IsZero(value, threshold)); - } - - [Theory] - [InlineData(180, 180)] - [InlineData(360, 360)] - [InlineData(-360, 360)] - [InlineData(720, 0)] - [InlineData(450.0, 90.0)] [InlineData(-90.0, 270.0)] [InlineData(-450.0, 270.0)] - [InlineData(0.0, 0.0)] - public void NormalizeAngleTest(double number, double expected) + [InlineData(90.0, 90.0)] + public void NormalizeAngle_Absolute_ReturnsExpected(double number, double expected) { - Assert.Equal(expected, MathHelper.NormalizeAngle(number)); + Assert.Equal(expected, MathHelper.NormalizeAngle(number, true)); } [Theory] @@ -212,12 +207,47 @@ public void NormalizeAngle_NotAbsolute_ReturnsExpected(double number, double exp } [Theory] + [InlineData(0.0, 0.0)] + [InlineData(MathHelper.HalfPI, MathHelper.HalfPI)] + [InlineData(MathHelper.TwoPI, MathHelper.TwoPI)] + [InlineData(-MathHelper.TwoPI, -MathHelper.TwoPI)] + [InlineData(2.0 * MathHelper.TwoPI, 0.0)] + [InlineData(-2.0 * MathHelper.TwoPI, 0.0)] + [InlineData(-MathHelper.HalfPI, -MathHelper.HalfPI)] + [InlineData(-MathHelper.PI, -MathHelper.PI)] + [InlineData(-(MathHelper.TwoPI + MathHelper.HalfPI), -MathHelper.HalfPI)] + public void NormalizeAngleRadians_NotAbsolute_ReturnsExpected(double angle, double expected) + { + Assert.Equal(expected, MathHelper.NormalizeAngleRadians(angle, false), 10); + } + + [Theory] + [InlineData(0.0, 0.0)] + [InlineData(MathHelper.HalfPI, MathHelper.HalfPI)] + [InlineData(MathHelper.PI, MathHelper.PI)] + [InlineData(MathHelper.TwoPI, MathHelper.TwoPI)] + [InlineData(-MathHelper.TwoPI, MathHelper.TwoPI)] + [InlineData(2.0 * MathHelper.TwoPI, 0.0)] + [InlineData(MathHelper.TwoPI + MathHelper.HalfPI, MathHelper.HalfPI)] + [InlineData(-MathHelper.HalfPI, MathHelper.ThreeHalfPI)] + [InlineData(-(MathHelper.TwoPI + MathHelper.HalfPI), MathHelper.ThreeHalfPI)] + public void NormalizeAngleRadians_ReturnsExpected(double angle, double expected) + { + Assert.Equal(expected, MathHelper.NormalizeAngleRadians(angle), 10); + } + + [Theory] + [InlineData(180, 180)] + [InlineData(360, 360)] + [InlineData(-360, 360)] + [InlineData(720, 0)] + [InlineData(450.0, 90.0)] [InlineData(-90.0, 270.0)] [InlineData(-450.0, 270.0)] - [InlineData(90.0, 90.0)] - public void NormalizeAngle_Absolute_ReturnsExpected(double number, double expected) + [InlineData(0.0, 0.0)] + public void NormalizeAngleTest(double number, double expected) { - Assert.Equal(expected, MathHelper.NormalizeAngle(number, true)); + Assert.Equal(expected, MathHelper.NormalizeAngle(number)); } [Theory] diff --git a/CSMath/MathHelper.cs b/CSMath/MathHelper.cs index 7c47a02..b116af6 100644 --- a/CSMath/MathHelper.cs +++ b/CSMath/MathHelper.cs @@ -327,14 +327,26 @@ public static double NormalizeAngle(double angle, bool absolute = true) /// Angle in radians. /// If true, negative angles will be converted to its positive equivalent. /// The equivalent angle in the range 0-2π. + /// Negative angles will be converted to its positive equivalent when is true. public static double NormalizeAngleRadians(double angle, bool absolute = true) { - if (angle < 0.0 || angle > TwoPI) + if (IsEqual(Math.Abs(angle), TwoPI)) { - angle -= TwoPI * Math.Floor(angle / TwoPI); + return angle < 0 && !absolute ? -TwoPI : TwoPI; } - return angle; + double normalized = angle % TwoPI; + if (IsZero(normalized)) + { + return 0.0; + } + + if (normalized < 0 && absolute) + { + return TwoPI + normalized; + } + + return normalized; } /// From c853f569b50fb00a7cac93de46675b37df72bb7b Mon Sep 17 00:00:00 2001 From: DomCR Date: Wed, 9 Sep 2026 08:12:21 +0200 Subject: [PATCH 3/9] Fix MathHelper tests and logic for angle normalization Corrected test expectations for IsEqual and NormalizeAngle. Added IsNegative(double) method. Updated NormalizeAngle to handle negative 360 values when absolute is false. --- CSMath.Tests/MathHelperTests.cs | 4 ++-- CSMath/MathHelper.cs | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CSMath.Tests/MathHelperTests.cs b/CSMath.Tests/MathHelperTests.cs index 51367b4..77d225a 100644 --- a/CSMath.Tests/MathHelperTests.cs +++ b/CSMath.Tests/MathHelperTests.cs @@ -153,7 +153,7 @@ public void IsEqual_CustomThreshold_ReturnsExpected(double a, double b, double t [Theory] [InlineData(1.0, 1.0000000000005, true)] [InlineData(5.0, 5.0, true)] - [InlineData(-5.0, 5.0, true)] + [InlineData(-5.0, 5.0, false)] [InlineData(5.0, 6.0, false)] public void IsEqual_ReturnsExpected(double a, double b, bool expected) { @@ -194,7 +194,7 @@ public void NormalizeAngle_Absolute_ReturnsExpected(double number, double expect [InlineData(0.0, 0.0)] [InlineData(180.0, 180.0)] [InlineData(360.0, 360.0)] - [InlineData(-360.0, 360.0)] + [InlineData(-360.0, -360.0)] [InlineData(720.0, 0.0)] [InlineData(450.0, 90.0)] [InlineData(-90.0, -90.0)] diff --git a/CSMath/MathHelper.cs b/CSMath/MathHelper.cs index b116af6..dcacacc 100644 --- a/CSMath/MathHelper.cs +++ b/CSMath/MathHelper.cs @@ -262,6 +262,16 @@ public static bool IsEven(this int value) return (value & 1) == 0; } + /// + /// Determines whether the specified double-precision floating-point value is negative. + /// + /// The value to evaluate. + /// True if the value is negative; otherwise, false. + public static bool IsNegative(double value) + { + return value < 0; + } + /// /// Determines whether the specified integer is odd. /// @@ -304,7 +314,7 @@ public static double NormalizeAngle(double angle, bool absolute = true) { if (IsEqual(Math.Abs(angle), 360.0)) { - return 360; + return angle < 0 && !absolute ? -360 : 360; } double normalized = angle % 360.0; From 371d0bd2f25faafac8d57f7c5ef7bc9908328cd8 Mon Sep 17 00:00:00 2001 From: DomCR Date: Wed, 9 Sep 2026 08:21:53 +0200 Subject: [PATCH 4/9] docs --- CSMath.Tests/MathHelperTests.cs | 1 + CSMath/MathHelper.cs | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CSMath.Tests/MathHelperTests.cs b/CSMath.Tests/MathHelperTests.cs index 77d225a..f6f2f13 100644 --- a/CSMath.Tests/MathHelperTests.cs +++ b/CSMath.Tests/MathHelperTests.cs @@ -153,6 +153,7 @@ public void IsEqual_CustomThreshold_ReturnsExpected(double a, double b, double t [Theory] [InlineData(1.0, 1.0000000000005, true)] [InlineData(5.0, 5.0, true)] + [InlineData(-5.0, -5.0, true)] [InlineData(-5.0, 5.0, false)] [InlineData(5.0, 6.0, false)] public void IsEqual_ReturnsExpected(double a, double b, bool expected) diff --git a/CSMath/MathHelper.cs b/CSMath/MathHelper.cs index dcacacc..5adc1ad 100644 --- a/CSMath/MathHelper.cs +++ b/CSMath/MathHelper.cs @@ -234,7 +234,7 @@ public static bool IsAngleInRange(double angle, double start, double end, double /// /// Double precision number. /// Double precision number. - /// True if its close to one or false in any other case. + /// True if the numbers are equal within a small tolerance; otherwise, false. public static bool IsEqual(double a, double b) { return IsEqual(a, b, Epsilon); @@ -246,9 +246,12 @@ public static bool IsEqual(double a, double b) /// Double precision number. /// Double precision number. /// Tolerance. - /// True if its close to one or false in any other case. + /// True if the numbers are equal within the specified tolerance; otherwise, false. public static bool IsEqual(double a, double b, double threshold) { + double diff = Math.Abs(a) - Math.Abs(b); + + return IsZero(Math.Abs(a) - Math.Abs(b), threshold); } @@ -286,7 +289,7 @@ public static bool IsOdd(this int value) /// Checks if a number is close to zero. /// /// Double precision number. - /// True if its close to one or false in any other case. + /// True if its close to zero; otherwise, false. public static bool IsZero(double number) { return IsZero(number, Epsilon); From 46aa83aa82929423a9fbfd033335b926c4c34a91 Mon Sep 17 00:00:00 2001 From: DomCR Date: Wed, 9 Sep 2026 08:25:58 +0200 Subject: [PATCH 5/9] IsEqual fix --- CSMath.Tests/MathHelperTests.cs | 1 + CSMath/MathHelper.cs | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CSMath.Tests/MathHelperTests.cs b/CSMath.Tests/MathHelperTests.cs index f6f2f13..c8f929d 100644 --- a/CSMath.Tests/MathHelperTests.cs +++ b/CSMath.Tests/MathHelperTests.cs @@ -155,6 +155,7 @@ public void IsEqual_CustomThreshold_ReturnsExpected(double a, double b, double t [InlineData(5.0, 5.0, true)] [InlineData(-5.0, -5.0, true)] [InlineData(-5.0, 5.0, false)] + [InlineData(5.0, -5.0, false)] [InlineData(5.0, 6.0, false)] public void IsEqual_ReturnsExpected(double a, double b, bool expected) { diff --git a/CSMath/MathHelper.cs b/CSMath/MathHelper.cs index 5adc1ad..94e022a 100644 --- a/CSMath/MathHelper.cs +++ b/CSMath/MathHelper.cs @@ -249,10 +249,7 @@ public static bool IsEqual(double a, double b) /// True if the numbers are equal within the specified tolerance; otherwise, false. public static bool IsEqual(double a, double b, double threshold) { - double diff = Math.Abs(a) - Math.Abs(b); - - - return IsZero(Math.Abs(a) - Math.Abs(b), threshold); + return IsZero(a - b, threshold); } /// From 2e5474ee9003eec08995f1610dca0b165a4f3a8b Mon Sep 17 00:00:00 2001 From: DomCR Date: Wed, 9 Sep 2026 08:29:23 +0200 Subject: [PATCH 6/9] Refactor angle normalization logic into helper method Extracted shared normalization logic from `NormalizeAngle` and `NormalizeAngleRadians` into a new private `normalizeAngle` method. This reduces code duplication and improves maintainability. --- CSMath/MathHelper.cs | 57 ++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/CSMath/MathHelper.cs b/CSMath/MathHelper.cs index 94e022a..2257da4 100644 --- a/CSMath/MathHelper.cs +++ b/CSMath/MathHelper.cs @@ -312,23 +312,7 @@ public static bool IsZero(double number, double threshold) /// Negative angles will be converted to its positive equivalent. public static double NormalizeAngle(double angle, bool absolute = true) { - if (IsEqual(Math.Abs(angle), 360.0)) - { - return angle < 0 && !absolute ? -360 : 360; - } - - double normalized = angle % 360.0; - if (IsZero(normalized)) - { - return 0.0; - } - - if (normalized < 0 && absolute) - { - return 360.0 + normalized; - } - - return normalized; + return normalizeAngle(angle, 360.0, absolute); } /// @@ -340,23 +324,7 @@ public static double NormalizeAngle(double angle, bool absolute = true) /// Negative angles will be converted to its positive equivalent when is true. public static double NormalizeAngleRadians(double angle, bool absolute = true) { - if (IsEqual(Math.Abs(angle), TwoPI)) - { - return angle < 0 && !absolute ? -TwoPI : TwoPI; - } - - double normalized = angle % TwoPI; - if (IsZero(normalized)) - { - return 0.0; - } - - if (normalized < 0 && absolute) - { - return TwoPI + normalized; - } - - return normalized; + return normalizeAngle(angle, TwoPI, absolute); } /// @@ -404,4 +372,25 @@ public static double Sin(double value) double result = Math.Sin(value); return IsZero(result) ? 0 : result; } + + private static double normalizeAngle(double angle, double fullCircle, bool absolute) + { + if (IsEqual(Math.Abs(angle), fullCircle)) + { + return angle < 0 && !absolute ? -fullCircle : fullCircle; + } + + double normalized = angle % fullCircle; + if (IsZero(normalized)) + { + return 0.0; + } + + if (normalized < 0 && absolute) + { + return fullCircle + normalized; + } + + return normalized; + } } \ No newline at end of file From e90593fdfa9d0de7b2451f58e1f603950fdcec35 Mon Sep 17 00:00:00 2001 From: DomCR Date: Wed, 9 Sep 2026 08:48:02 +0200 Subject: [PATCH 7/9] extensions --- CSMath.Tests/AssertUtils.cs | 3 +- .../Extensions/DoubleExtensionsTests.cs | 28 +++++++ CSMath.Tests/Extensions/IntExtensionsTests.cs | 11 +++ CSMath.Tests/Geometry/Arc2DTests.cs | 1 - CSMath.Tests/Geometry/Circle2DTests.cs | 11 +-- CSMath.Tests/Geometry/Segment2DTests.cs | 3 +- CSMath.Tests/Geometry/Segment3DTests.cs | 3 +- CSMath.Tests/MathHelperTests.cs | 34 -------- CSMath.Tests/VectorExtensionsTests.cs | 6 +- CSMath.Tests/VectorTests.cs | 1 + CSMath.Tests/XYTest.cs | 3 +- CSMath/CSMath.projitems | 4 +- CSMath/Extensions/DoubleExtensions.cs | 25 ++++++ CSMath/Extensions/IntExtensions.cs | 34 ++++++++ CSMath/{ => Extensions}/VectorExtensions.cs | 4 +- CSMath/Geometry/Arc2D.cs | 3 +- CSMath/Geometry/Circle2D.cs | 5 +- CSMath/Geometry/Line2D.cs | 1 + CSMath/Geometry/Line3D.cs | 3 +- CSMath/Geometry/LineExtensions.cs | 3 +- CSMath/Geometry/Segment2D.cs | 3 +- CSMath/Geometry/Segment3D.cs | 3 +- CSMath/IVector.cs | 4 +- CSMath/MathHelper.cs | 79 ++----------------- CSMath/Matrix3.cs | 3 +- CSMath/Matrix4.Operators.cs | 2 +- CSMath/Matrix4.cs | 3 +- CSMath/Quaternion.cs | 3 +- CSMath/Transform.cs | 3 +- CSMath/XY.cs | 3 +- CSMath/XY.operators.cs | 3 +- CSMath/XYZ.cs | 5 +- CSMath/XYZ.operators.cs | 3 +- CSMath/XYZM.cs | 3 +- CSMath/XYZM.operators.cs | 3 +- .../Converters/BaseEndianConverterTests.cs | 1 - .../Converters/BigEndianConverterTests.cs | 1 - .../Extensions/IEnumerableExtensionsTests.cs | 3 +- CSUtilities.Tests/Mock/IMockInterface.cs | 7 +- CSUtilities.Tests/TryTests.cs | 1 - 40 files changed, 165 insertions(+), 157 deletions(-) create mode 100644 CSMath.Tests/Extensions/DoubleExtensionsTests.cs create mode 100644 CSMath.Tests/Extensions/IntExtensionsTests.cs create mode 100644 CSMath/Extensions/DoubleExtensions.cs create mode 100644 CSMath/Extensions/IntExtensions.cs rename CSMath/{ => Extensions}/VectorExtensions.cs (99%) diff --git a/CSMath.Tests/AssertUtils.cs b/CSMath.Tests/AssertUtils.cs index dfc6af3..0d6a8c9 100644 --- a/CSMath.Tests/AssertUtils.cs +++ b/CSMath.Tests/AssertUtils.cs @@ -1,4 +1,5 @@ -using Xunit; +using CSMath.Extensions; +using Xunit; namespace CSMath.Tests; diff --git a/CSMath.Tests/Extensions/DoubleExtensionsTests.cs b/CSMath.Tests/Extensions/DoubleExtensionsTests.cs new file mode 100644 index 0000000..9a2d730 --- /dev/null +++ b/CSMath.Tests/Extensions/DoubleExtensionsTests.cs @@ -0,0 +1,28 @@ +using CSMath.Extensions; +using Xunit; + +namespace CSMath.Tests.Extensions; + +public class DoubleExtensionsTests +{ + [Theory] + [InlineData(0.05, 0.1, true)] + [InlineData(0.2, 0.1, false)] + public void IsZero_CustomThreshold_ReturnsExpected(double value, double threshold, bool expected) + { + Assert.Equal(expected, value.IsZero(threshold)); + } + + [Theory] + [InlineData(0.0, true)] + [InlineData(5e-13, true)] + [InlineData(-5e-13, true)] + [InlineData(1e-12, true)] + [InlineData(-1e-12, true)] + [InlineData(1.0, false)] + [InlineData(-1.0, false)] + public void IsZero_ReturnsExpected(double value, bool expected) + { + Assert.Equal(expected, value.IsZero()); + } +} \ No newline at end of file diff --git a/CSMath.Tests/Extensions/IntExtensionsTests.cs b/CSMath.Tests/Extensions/IntExtensionsTests.cs new file mode 100644 index 0000000..90aa05a --- /dev/null +++ b/CSMath.Tests/Extensions/IntExtensionsTests.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSMath.Tests.Extensions; + +internal class IntExtensionsTests +{ +} diff --git a/CSMath.Tests/Geometry/Arc2DTests.cs b/CSMath.Tests/Geometry/Arc2DTests.cs index 5536be4..687ed40 100644 --- a/CSMath.Tests/Geometry/Arc2DTests.cs +++ b/CSMath.Tests/Geometry/Arc2DTests.cs @@ -1,6 +1,5 @@ using CSMath.Geometry; using System; -using System.Collections.Generic; using System.Linq; using Xunit; diff --git a/CSMath.Tests/Geometry/Circle2DTests.cs b/CSMath.Tests/Geometry/Circle2DTests.cs index 31e01ef..6b4528c 100644 --- a/CSMath.Tests/Geometry/Circle2DTests.cs +++ b/CSMath.Tests/Geometry/Circle2DTests.cs @@ -1,3 +1,4 @@ +using CSMath.Extensions; using CSMath.Geometry; using System.Linq; using Xunit; @@ -114,8 +115,8 @@ public void FindIntersections_WithLineNegativeDirection_ReturnsTwoIntersections( Assert.Equal(2, intersections.Length); // Both points should be at x=0 - Assert.True(MathHelper.IsZero(intersections[0].X, 1e-10)); - Assert.True(MathHelper.IsZero(intersections[1].X, 1e-10)); + Assert.True(intersections[0].X.IsZero(1e-10)); + Assert.True(intersections[1].X.IsZero(1e-10)); // Both points should be on the circle double distance1 = intersections[0].GetLength(); @@ -137,9 +138,9 @@ public void FindIntersections_WithLineThroughCenter_ReturnsTwoIntersections() // Assert Assert.Equal(2, intersections.Length); Assert.True(MathHelper.IsEqual(5.0, intersections[0].X, 1e-10) || MathHelper.IsEqual(-5.0, intersections[0].X, 1e-10)); - Assert.True(MathHelper.IsZero(intersections[0].Y, 1e-10)); + Assert.True(intersections[0].Y.IsZero(1e-10)); Assert.True(MathHelper.IsEqual(5.0, intersections[1].X, 1e-10) || MathHelper.IsEqual(-5.0, intersections[1].X, 1e-10)); - Assert.True(MathHelper.IsZero(intersections[1].Y, 1e-10)); + Assert.True(intersections[1].Y.IsZero(1e-10)); } [Fact] @@ -213,6 +214,6 @@ public void FindIntersections_WithTangentLine_ReturnsOneIntersection() // Assert Assert.Single(intersections); Assert.True(MathHelper.IsEqual(5.0, intersections[0].X, 1e-10)); - Assert.True(MathHelper.IsZero(intersections[0].Y, 1e-10)); + Assert.True(intersections[0].Y.IsZero(1e-10)); } } \ No newline at end of file diff --git a/CSMath.Tests/Geometry/Segment2DTests.cs b/CSMath.Tests/Geometry/Segment2DTests.cs index 7233348..36eb561 100644 --- a/CSMath.Tests/Geometry/Segment2DTests.cs +++ b/CSMath.Tests/Geometry/Segment2DTests.cs @@ -1,4 +1,5 @@ -using CSMath.Geometry; +using CSMath.Extensions; +using CSMath.Geometry; using Xunit; namespace CSMath.Tests.Geometry; diff --git a/CSMath.Tests/Geometry/Segment3DTests.cs b/CSMath.Tests/Geometry/Segment3DTests.cs index 15dd16d..a74ee3d 100644 --- a/CSMath.Tests/Geometry/Segment3DTests.cs +++ b/CSMath.Tests/Geometry/Segment3DTests.cs @@ -1,4 +1,5 @@ -using CSMath.Geometry; +using CSMath.Extensions; +using CSMath.Geometry; using Xunit; namespace CSMath.Tests.Geometry; diff --git a/CSMath.Tests/MathHelperTests.cs b/CSMath.Tests/MathHelperTests.cs index c8f929d..a18edb7 100644 --- a/CSMath.Tests/MathHelperTests.cs +++ b/CSMath.Tests/MathHelperTests.cs @@ -129,19 +129,6 @@ public void HalfPI_IsCorrect() Assert.Equal(Math.PI / 2.0, MathHelper.HalfPI); } - [Theory] - [InlineData(0.0, true)] - [InlineData(5e-13, true)] - [InlineData(-5e-13, true)] - [InlineData(1e-12, false)] - [InlineData(-1e-12, false)] - [InlineData(1.0, false)] - [InlineData(-1.0, false)] - public void IsAlmostZero_ReturnsExpected(double value, bool expected) - { - Assert.Equal(expected, MathHelper.IsAlmostZero(value)); - } - [Theory] [InlineData(1.0, 1.05, 0.1, true)] [InlineData(1.0, 1.5, 0.1, false)] @@ -162,27 +149,6 @@ public void IsEqual_ReturnsExpected(double a, double b, bool expected) Assert.Equal(expected, MathHelper.IsEqual(a, b)); } - [Theory] - [InlineData(0.05, 0.1, true)] - [InlineData(0.2, 0.1, false)] - public void IsZero_CustomThreshold_ReturnsExpected(double value, double threshold, bool expected) - { - Assert.Equal(expected, MathHelper.IsZero(value, threshold)); - } - - [Theory] - [InlineData(0.0, true)] - [InlineData(5e-13, true)] - [InlineData(-5e-13, true)] - [InlineData(1e-12, true)] - [InlineData(-1e-12, true)] - [InlineData(1.0, false)] - [InlineData(-1.0, false)] - public void IsZero_ReturnsExpected(double value, bool expected) - { - Assert.Equal(expected, MathHelper.IsZero(value)); - } - [Theory] [InlineData(-90.0, 270.0)] [InlineData(-450.0, 270.0)] diff --git a/CSMath.Tests/VectorExtensionsTests.cs b/CSMath.Tests/VectorExtensionsTests.cs index 3c146b8..153ef63 100644 --- a/CSMath.Tests/VectorExtensionsTests.cs +++ b/CSMath.Tests/VectorExtensionsTests.cs @@ -1,10 +1,6 @@ using Xunit; -using CSMath; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using CSMath.Extensions; namespace CSMath.Tests; diff --git a/CSMath.Tests/VectorTests.cs b/CSMath.Tests/VectorTests.cs index 3937d3f..06f8916 100644 --- a/CSMath.Tests/VectorTests.cs +++ b/CSMath.Tests/VectorTests.cs @@ -1,3 +1,4 @@ +using CSMath.Extensions; using System; using System.Linq; using Xunit; diff --git a/CSMath.Tests/XYTest.cs b/CSMath.Tests/XYTest.cs index 0f99ad5..19ba438 100644 --- a/CSMath.Tests/XYTest.cs +++ b/CSMath.Tests/XYTest.cs @@ -1,4 +1,5 @@ -using Xunit; +using CSMath.Extensions; +using Xunit; using Xunit.Abstractions; namespace CSMath.Tests; diff --git a/CSMath/CSMath.projitems b/CSMath/CSMath.projitems index b437265..dbb146a 100644 --- a/CSMath/CSMath.projitems +++ b/CSMath/CSMath.projitems @@ -11,6 +11,8 @@ + + @@ -29,7 +31,7 @@ - + diff --git a/CSMath/Extensions/DoubleExtensions.cs b/CSMath/Extensions/DoubleExtensions.cs new file mode 100644 index 0000000..3d5f0cc --- /dev/null +++ b/CSMath/Extensions/DoubleExtensions.cs @@ -0,0 +1,25 @@ +namespace CSMath.Extensions; + +public static class DoubleExtensions +{ + /// + /// Determines whether the specified double is zero, using a default threshold for comparison. + /// + /// The double value to evaluate. + /// True if the number is zero within the default threshold; otherwise, false. + public static bool IsZero(this double value) + { + return value.IsZero(MathHelper.Epsilon); + } + + /// + /// Determines whether the specified double is zero, using a custom threshold for comparison. + /// + /// The double value to evaluate. + /// The custom threshold for comparison. + /// True if the number is zero within the specified threshold; otherwise, false. + public static bool IsZero(this double value, double threshold) + { + return value >= -threshold && value <= threshold; + } +} \ No newline at end of file diff --git a/CSMath/Extensions/IntExtensions.cs b/CSMath/Extensions/IntExtensions.cs new file mode 100644 index 0000000..d6a6f4c --- /dev/null +++ b/CSMath/Extensions/IntExtensions.cs @@ -0,0 +1,34 @@ +namespace CSMath.Extensions; + +public static class IntExtensions +{ + /// + /// Determines whether the specified integer is even. + /// + /// The integer to evaluate. + /// True if the integer is even; otherwise, false. + public static bool IsEven(this int value) + { + return (value & 1) == 0; + } + + /// + /// Determines whether the specified integer is odd. + /// + /// The integer to evaluate. + /// True if the integer is odd; otherwise, false. + public static bool IsNegative(this int value) + { + return value < 0; + } + + /// + /// Determines whether the specified integer is odd. + /// + /// The integer to evaluate. + /// True if the integer is odd; otherwise, false. + public static bool IsOdd(this int value) + { + return (value & 1) == 1; + } +} \ No newline at end of file diff --git a/CSMath/VectorExtensions.cs b/CSMath/Extensions/VectorExtensions.cs similarity index 99% rename from CSMath/VectorExtensions.cs rename to CSMath/Extensions/VectorExtensions.cs index 8da7d59..9c42877 100644 --- a/CSMath/VectorExtensions.cs +++ b/CSMath/Extensions/VectorExtensions.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace CSMath; +namespace CSMath.Extensions; public static class VectorExtensions { @@ -393,7 +393,7 @@ public static T RoundZero(this T vector, double threshold = MathHelper.Epsilo for (int i = 0; i < result.Dimension; i++) { - result[i] = MathHelper.IsZero(vector[i], threshold) ? 0 : vector[i]; + result[i] = vector[i].IsZero(threshold) ? 0 : vector[i]; } return result; diff --git a/CSMath/Geometry/Arc2D.cs b/CSMath/Geometry/Arc2D.cs index f25923b..2258760 100644 --- a/CSMath/Geometry/Arc2D.cs +++ b/CSMath/Geometry/Arc2D.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using CSMath.Extensions; +using System.Collections.Generic; using System.Linq; namespace CSMath.Geometry; diff --git a/CSMath/Geometry/Circle2D.cs b/CSMath/Geometry/Circle2D.cs index 2e272e7..81a5c5b 100644 --- a/CSMath/Geometry/Circle2D.cs +++ b/CSMath/Geometry/Circle2D.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using CSMath.Extensions; +using System.Collections.Generic; using System.Linq; namespace CSMath.Geometry; @@ -58,7 +59,7 @@ public IEnumerable FindIntersections(Line2D line) double determinant = XY.Cross(relativeOrigin, line.Direction); double discriminant = this.Radius * this.Radius * lengthSquared - determinant * determinant; - if (MathHelper.IsZero(discriminant)) + if (discriminant.IsZero()) { double x = determinant * line.Direction.Y / lengthSquared; double y = -determinant * line.Direction.X / lengthSquared; diff --git a/CSMath/Geometry/Line2D.cs b/CSMath/Geometry/Line2D.cs index 156ded9..f303041 100644 --- a/CSMath/Geometry/Line2D.cs +++ b/CSMath/Geometry/Line2D.cs @@ -1,3 +1,4 @@ +using CSMath.Extensions; using System; namespace CSMath.Geometry; diff --git a/CSMath/Geometry/Line3D.cs b/CSMath/Geometry/Line3D.cs index aef0e24..f6173cf 100644 --- a/CSMath/Geometry/Line3D.cs +++ b/CSMath/Geometry/Line3D.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath.Geometry; diff --git a/CSMath/Geometry/LineExtensions.cs b/CSMath/Geometry/LineExtensions.cs index 56cdcaf..b928e1f 100644 --- a/CSMath/Geometry/LineExtensions.cs +++ b/CSMath/Geometry/LineExtensions.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath.Geometry; diff --git a/CSMath/Geometry/Segment2D.cs b/CSMath/Geometry/Segment2D.cs index 12bcdbd..8b11260 100644 --- a/CSMath/Geometry/Segment2D.cs +++ b/CSMath/Geometry/Segment2D.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath.Geometry; diff --git a/CSMath/Geometry/Segment3D.cs b/CSMath/Geometry/Segment3D.cs index 4ee843b..c0649af 100644 --- a/CSMath/Geometry/Segment3D.cs +++ b/CSMath/Geometry/Segment3D.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath.Geometry; diff --git a/CSMath/IVector.cs b/CSMath/IVector.cs index 59af5d0..75089a8 100644 --- a/CSMath/IVector.cs +++ b/CSMath/IVector.cs @@ -1,6 +1,4 @@ -using System; - -namespace CSMath; +namespace CSMath; public interface IVector { diff --git a/CSMath/MathHelper.cs b/CSMath/MathHelper.cs index 2257da4..11d0376 100644 --- a/CSMath/MathHelper.cs +++ b/CSMath/MathHelper.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath; @@ -75,7 +76,7 @@ public static class MathHelper public static double Cos(double value) { double result = Math.Cos(value); - return IsZero(result) ? 0 : result; + return result.IsZero() ? 0 : result; } /// @@ -116,7 +117,7 @@ public static double FixZero(double number) /// Zero if the number is within the threshold; otherwise, the original number. public static double FixZero(double number, double threshold) { - return IsZero(number, threshold) ? 0 : number; + return number.IsZero(threshold) ? 0 : number; } /// @@ -185,21 +186,6 @@ public static double GradToRad(double value) return value * GradToRadFactor; } - /// - /// Determines whether the specified double-precision floating-point value is approximately zero, within a small - /// tolerance. - /// - /// The value to compare to zero. - /// true if the value is within a small range of zero; otherwise, false. - public static bool IsAlmostZero(double value) - { - if (value > -Epsilon) - { - return value < Epsilon; - } - return false; - } - /// /// Determines whether a specified angle falls within a given angular range. /// @@ -249,58 +235,7 @@ public static bool IsEqual(double a, double b) /// True if the numbers are equal within the specified tolerance; otherwise, false. public static bool IsEqual(double a, double b, double threshold) { - return IsZero(a - b, threshold); - } - - /// - /// Determines whether the specified integer is even. - /// - /// The integer to evaluate. - /// True if the integer is even; otherwise, false. - public static bool IsEven(this int value) - { - return (value & 1) == 0; - } - - /// - /// Determines whether the specified double-precision floating-point value is negative. - /// - /// The value to evaluate. - /// True if the value is negative; otherwise, false. - public static bool IsNegative(double value) - { - return value < 0; - } - - /// - /// Determines whether the specified integer is odd. - /// - /// The integer to evaluate. - /// True if the integer is odd; otherwise, false. - public static bool IsOdd(this int value) - { - return (value & 1) == 1; - } - - /// - /// Checks if a number is close to zero. - /// - /// Double precision number. - /// True if its close to zero; otherwise, false. - public static bool IsZero(double number) - { - return IsZero(number, Epsilon); - } - - /// - /// Checks if a number is close to zero. - /// - /// Double precision number. - /// Tolerance. - /// True if its close to one or false in any other case. - public static bool IsZero(double number, double threshold) - { - return number >= -threshold && number <= threshold; + return (a - b).IsZero(threshold); } /// @@ -370,7 +305,7 @@ public static double RoundToNearest(double number, double roundTo) public static double Sin(double value) { double result = Math.Sin(value); - return IsZero(result) ? 0 : result; + return result.IsZero() ? 0 : result; } private static double normalizeAngle(double angle, double fullCircle, bool absolute) @@ -381,7 +316,7 @@ private static double normalizeAngle(double angle, double fullCircle, bool absol } double normalized = angle % fullCircle; - if (IsZero(normalized)) + if (normalized.IsZero()) { return 0.0; } diff --git a/CSMath/Matrix3.cs b/CSMath/Matrix3.cs index c2862d6..9e732d1 100644 --- a/CSMath/Matrix3.cs +++ b/CSMath/Matrix3.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; using System.Text; using System.Threading; diff --git a/CSMath/Matrix4.Operators.cs b/CSMath/Matrix4.Operators.cs index 1658f85..4a47280 100644 --- a/CSMath/Matrix4.Operators.cs +++ b/CSMath/Matrix4.Operators.cs @@ -1,4 +1,4 @@ -using System; +using CSMath.Extensions; using System.Collections.Generic; namespace CSMath; diff --git a/CSMath/Matrix4.cs b/CSMath/Matrix4.cs index acb2797..a487122 100644 --- a/CSMath/Matrix4.cs +++ b/CSMath/Matrix4.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; using System.Collections.Generic; using System.Text; using System.Threading; diff --git a/CSMath/Quaternion.cs b/CSMath/Quaternion.cs index 03fb3cb..48bc0e9 100644 --- a/CSMath/Quaternion.cs +++ b/CSMath/Quaternion.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath; diff --git a/CSMath/Transform.cs b/CSMath/Transform.cs index 65caba1..38bf39e 100644 --- a/CSMath/Transform.cs +++ b/CSMath/Transform.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath; diff --git a/CSMath/XY.cs b/CSMath/XY.cs index e5dea28..8d52478 100644 --- a/CSMath/XY.cs +++ b/CSMath/XY.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath; diff --git a/CSMath/XY.operators.cs b/CSMath/XY.operators.cs index c41fc3c..6b7d80d 100644 --- a/CSMath/XY.operators.cs +++ b/CSMath/XY.operators.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath; diff --git a/CSMath/XYZ.cs b/CSMath/XYZ.cs index 80639d6..73f7097 100644 --- a/CSMath/XYZ.cs +++ b/CSMath/XYZ.cs @@ -1,4 +1,5 @@ using System; +using CSMath.Extensions; namespace CSMath; @@ -121,7 +122,7 @@ public bool Equals(XYZ other) public double GetAngle(XYZ dir) { double t = this.Dot(dir) / Math.Sqrt(this.GetLengthSquared() * dir.GetLengthSquared()); - if (MathHelper.IsAlmostZero(Math.Abs(t) - 1.0d)) + if ((Math.Abs(t) - 1.0d).IsZero()) { if (!((double)t > 0.0)) { @@ -146,7 +147,7 @@ public double GetAngle(XYZ dir) public double GetAngle(XYZ dir, XYZ normal) { double t = this.Dot(dir) / Math.Sqrt(this.GetLengthSquared() * dir.GetLengthSquared()); - if (MathHelper.IsAlmostZero(Math.Abs(t) - 1.0d)) + if ((Math.Abs(t) - 1.0d).IsZero()) { if (!((double)t > 0.0)) { diff --git a/CSMath/XYZ.operators.cs b/CSMath/XYZ.operators.cs index 0a5eaa0..7e6a67e 100644 --- a/CSMath/XYZ.operators.cs +++ b/CSMath/XYZ.operators.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath; diff --git a/CSMath/XYZM.cs b/CSMath/XYZM.cs index 8b95856..96bb317 100644 --- a/CSMath/XYZM.cs +++ b/CSMath/XYZM.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath; diff --git a/CSMath/XYZM.operators.cs b/CSMath/XYZM.operators.cs index 344a337..1197345 100644 --- a/CSMath/XYZM.operators.cs +++ b/CSMath/XYZM.operators.cs @@ -1,4 +1,5 @@ -using System; +using CSMath.Extensions; +using System; namespace CSMath; diff --git a/CSUtilities.Tests/Converters/BaseEndianConverterTests.cs b/CSUtilities.Tests/Converters/BaseEndianConverterTests.cs index 0d71086..0deb889 100644 --- a/CSUtilities.Tests/Converters/BaseEndianConverterTests.cs +++ b/CSUtilities.Tests/Converters/BaseEndianConverterTests.cs @@ -1,5 +1,4 @@ using CSUtilities.Converters; -using System; using Xunit; namespace CSUtilities.Tests.Converters; diff --git a/CSUtilities.Tests/Converters/BigEndianConverterTests.cs b/CSUtilities.Tests/Converters/BigEndianConverterTests.cs index 2846201..4b7d045 100644 --- a/CSUtilities.Tests/Converters/BigEndianConverterTests.cs +++ b/CSUtilities.Tests/Converters/BigEndianConverterTests.cs @@ -1,5 +1,4 @@ using CSUtilities.Converters; -using System; using Xunit; namespace CSUtilities.Tests.Converters; diff --git a/CSUtilities.Tests/Extensions/IEnumerableExtensionsTests.cs b/CSUtilities.Tests/Extensions/IEnumerableExtensionsTests.cs index 571f676..380fa57 100644 --- a/CSUtilities.Tests/Extensions/IEnumerableExtensionsTests.cs +++ b/CSUtilities.Tests/Extensions/IEnumerableExtensionsTests.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using CSUtilities.Extensions; using Xunit; diff --git a/CSUtilities.Tests/Mock/IMockInterface.cs b/CSUtilities.Tests/Mock/IMockInterface.cs index 8fafeb2..9b0e8ec 100644 --- a/CSUtilities.Tests/Mock/IMockInterface.cs +++ b/CSUtilities.Tests/Mock/IMockInterface.cs @@ -1,9 +1,4 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CSUtilities.Tests.Mock; +namespace CSUtilities.Tests.Mock; public interface IMockInterface { diff --git a/CSUtilities.Tests/TryTests.cs b/CSUtilities.Tests/TryTests.cs index dfe8a97..e661b6e 100644 --- a/CSUtilities.Tests/TryTests.cs +++ b/CSUtilities.Tests/TryTests.cs @@ -1,5 +1,4 @@ using System; -using CSUtilities; using Xunit; namespace CSUtilities.Tests; From 55e18f5ffb3771ead4e20d5975b625895049f6a9 Mon Sep 17 00:00:00 2001 From: DomCR Date: Wed, 9 Sep 2026 09:06:29 +0200 Subject: [PATCH 8/9] Improve floating-point zero checks in VectorExtensions Replaced direct equality checks with IsZero() in IsPerpendicular and IsZero methods for better floating-point accuracy. Added a test case to MathHelperTests to verify that large, nearly equal numbers are not considered equal. --- CSMath.Tests/MathHelperTests.cs | 1 + CSMath/Extensions/VectorExtensions.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CSMath.Tests/MathHelperTests.cs b/CSMath.Tests/MathHelperTests.cs index a18edb7..bb476fb 100644 --- a/CSMath.Tests/MathHelperTests.cs +++ b/CSMath.Tests/MathHelperTests.cs @@ -144,6 +144,7 @@ public void IsEqual_CustomThreshold_ReturnsExpected(double a, double b, double t [InlineData(-5.0, 5.0, false)] [InlineData(5.0, -5.0, false)] [InlineData(5.0, 6.0, false)] + [InlineData(1e16, 1e16 + 2, false)] public void IsEqual_ReturnsExpected(double a, double b, bool expected) { Assert.Equal(expected, MathHelper.IsEqual(a, b)); diff --git a/CSMath/Extensions/VectorExtensions.cs b/CSMath/Extensions/VectorExtensions.cs index 9c42877..b016d2a 100644 --- a/CSMath/Extensions/VectorExtensions.cs +++ b/CSMath/Extensions/VectorExtensions.cs @@ -262,7 +262,7 @@ public static bool IsParallel(this T left, T right) public static bool IsPerpendicular(this T left, T right) where T : IVector { - return Dot(left, right) == 0; + return Dot(left, right).IsZero(); } /// @@ -274,7 +274,7 @@ public static bool IsPerpendicular(this T left, T right) public static bool IsZero(this T v) where T : IVector { - return v.GetLength() == 0; + return v.GetLength().IsZero(); } /// From 4362bf99ccca3875d6d2eded411a070a06246a3c Mon Sep 17 00:00:00 2001 From: DomCR Date: Wed, 9 Sep 2026 09:07:41 +0200 Subject: [PATCH 9/9] tests --- CSMath.Tests/Extensions/IntExtensionsTests.cs | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/CSMath.Tests/Extensions/IntExtensionsTests.cs b/CSMath.Tests/Extensions/IntExtensionsTests.cs index 90aa05a..4cc63dd 100644 --- a/CSMath.Tests/Extensions/IntExtensionsTests.cs +++ b/CSMath.Tests/Extensions/IntExtensionsTests.cs @@ -1,11 +1,44 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using CSMath.Extensions; +using Xunit; namespace CSMath.Tests.Extensions; -internal class IntExtensionsTests +public class IntExtensionsTests { + [Theory] + [InlineData(0, true)] + [InlineData(2, true)] + [InlineData(-2, true)] + [InlineData(1, false)] + [InlineData(-1, false)] + [InlineData(int.MaxValue, false)] + [InlineData(int.MinValue, true)] + public void IsEven_ReturnsExpected(int value, bool expected) + { + Assert.Equal(expected, value.IsEven()); + } + + [Theory] + [InlineData(0, false)] + [InlineData(1, false)] + [InlineData(-1, true)] + [InlineData(int.MaxValue, false)] + [InlineData(int.MinValue, true)] + public void IsNegative_ReturnsExpected(int value, bool expected) + { + Assert.Equal(expected, value.IsNegative()); + } + + [Theory] + [InlineData(0, false)] + [InlineData(2, false)] + [InlineData(-2, false)] + [InlineData(1, true)] + [InlineData(-1, true)] + [InlineData(int.MaxValue, true)] + [InlineData(int.MinValue, false)] + public void IsOdd_ReturnsExpected(int value, bool expected) + { + Assert.Equal(expected, value.IsOdd()); + } }