Skip to content

Commit

Permalink
Improve S1244: Add message to use "IsXInfinity()" instead of "== doub…
Browse files Browse the repository at this point in the history
…le.XInfinity" (#6670)
  • Loading branch information
antonioaversa authored Feb 1, 2023
1 parent bbd3433 commit e45a03a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public sealed class EqualityOnFloatingPoint : SonarDiagnosticAnalyzer
private static readonly Dictionary<string, string> SpecialMembers = new()
{
{ nameof(double.NaN), nameof(double.IsNaN) },
{ nameof(double.PositiveInfinity), nameof(double.IsPositiveInfinity) },
{ nameof(double.NegativeInfinity), nameof(double.IsNegativeInfinity) },
};

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,31 @@
using System.Runtime.InteropServices;

public class EqualityOnFloatingPoint
{
bool HalfEqual(Half first, Half second) =>
first == second; // Noncompliant {{Do not check floating point equality with exact values, use a range instead.}}
// ^^

bool NFloatEqual(NFloat first, NFloat second) =>
first == second; // Noncompliant

bool IsEpsilon<T>(T value) where T : IFloatingPointIeee754<T> =>
value == T.Epsilon; // Noncompliant

bool IsPi<T>(T value) where T : IFloatingPointIeee754<T> =>
value <= T.Pi && ((value >= T.Pi)); // Noncompliant

bool IsNotE<T>(T value) where T : IFloatingPointIeee754<T> =>
value > T.E || ((value < T.E)); // Noncompliant

bool AreEqual<T>(T first, T second) where T : IFloatingPointIeee754<T> =>
first == second; // Noncompliant

bool Equal<T>(T first, T second) where T : IBinaryFloatingPointIeee754<T> =>
first == second; // Noncompliant
}

public class ReportSpecificMessage_NaN
{
void HalfNaN(Half h)
{
Expand All @@ -22,26 +47,36 @@ public void M<T>(T t) where T : IFloatingPointIeee754<T>
if (t == T.NaN) { } // Noncompliant {{Do not check floating point equality with exact values, use 'T.IsNaN()' instead.}}
if (T.IsNaN(t)) { } // Compliant
}
}

bool HalfEqual(Half first, Half second)
=> first == second; // Noncompliant {{Do not check floating point equality with exact values, use a range instead.}}
// ^^

bool NFloatEqual(NFloat first, NFloat second)
=> first == second; // Noncompliant

bool IsEpsilon<T>(T value) where T : IFloatingPointIeee754<T>
=> value == T.Epsilon; // Noncompliant

bool IsPi<T>(T value) where T : IFloatingPointIeee754<T>
=> value <= T.Pi && ((value >= T.Pi)); // Noncompliant
public class ReportSpecificMessage_Infinities
{
void HalfInfinities(Half h)
{
_ = h == Half.PositiveInfinity; // Noncompliant {{Do not check floating point equality with exact values, use 'Half.IsPositiveInfinity()' instead.}}
_ = Half.NegativeInfinity == h; // Noncompliant {{Do not check floating point equality with exact values, use 'Half.IsNegativeInfinity()' instead.}}
}

bool IsNotE<T>(T value) where T : IFloatingPointIeee754<T>
=> value > T.E || ((value < T.E)); // Noncompliant
void NFloatInfinities(NFloat nf)
{
_ = nf == NFloat.PositiveInfinity; // Noncompliant {{Do not check floating point equality with exact values, use 'NFloat.IsPositiveInfinity()' instead.}}
_ = NFloat.NegativeInfinity == nf; // Noncompliant {{Do not check floating point equality with exact values, use 'NFloat.IsNegativeInfinity()' instead.}}
}
}

bool AreEqual<T>(T first, T second) where T : IFloatingPointIeee754<T>
=> first == second; // Noncompliant
namespace TestWithUsingStatic
{
using static System.Runtime.InteropServices.NFloat;

bool Equal<T>(T first, T second) where T : IBinaryFloatingPointIeee754<T>
=> first == second; // Noncompliant
public class ReportSpecificMessage
{
public void WithUsingStatic(double d)
{
_ = d == NaN; // Noncompliant {{Do not check floating point equality with exact values, use 'IsNaN()' instead.}}
_ = NaN == d; // Noncompliant {{Do not check floating point equality with exact values, use 'IsNaN()' instead.}}
_ = NaN == NaN; // Noncompliant {{Do not check floating point equality with exact values, use 'IsNaN()' instead.}}
_ = NaN == float.NaN; // Noncompliant {{Do not check floating point equality with exact values, use 'NFloat.IsNaN()' instead.}}
_ = double.NaN == NaN; // Noncompliant {{Do not check floating point equality with exact values, use 'double.IsNaN()' instead.}}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,37 @@ public void WithSingle()
}
}

public class ReportSpecificMessage_Infinities
{
public void WithDouble(double d)
{
_ = d == double.PositiveInfinity; // Noncompliant {{Do not check floating point equality with exact values, use 'double.IsPositiveInfinity()' instead.}}
_ = double.PositiveInfinity != d; // Noncompliant {{Do not check floating point inequality with exact values, use 'double.IsPositiveInfinity()' instead.}}
_ = d == double.NegativeInfinity; // Noncompliant {{Do not check floating point equality with exact values, use 'double.IsNegativeInfinity()' instead.}}
_ = double.NegativeInfinity != d; // Noncompliant {{Do not check floating point inequality with exact values, use 'double.IsNegativeInfinity()' instead.}}
}

public void WithFloat(float f)
{
_ = f == float.PositiveInfinity; // Noncompliant {{Do not check floating point equality with exact values, use 'float.IsPositiveInfinity()' instead.}}
_ = float.PositiveInfinity != f; // Noncompliant {{Do not check floating point inequality with exact values, use 'float.IsPositiveInfinity()' instead.}}
_ = f == float.NegativeInfinity; // Noncompliant {{Do not check floating point equality with exact values, use 'float.IsNegativeInfinity()' instead.}}
_ = float.NegativeInfinity != f; // Noncompliant {{Do not check floating point inequality with exact values, use 'float.IsNegativeInfinity()' instead.}}
}

public void WithDoublePascalCase(Double d)
{
_ = Double.PositiveInfinity == d; // Noncompliant {{Do not check floating point equality with exact values, use 'double.IsPositiveInfinity()' instead.}}
_ = d == System.Double.NegativeInfinity; // Noncompliant {{Do not check floating point equality with exact values, use 'double.IsNegativeInfinity()' instead.}}
}

public void WithSingle(Single f)
{
_ = Single.PositiveInfinity == f; // Noncompliant {{Do not check floating point equality with exact values, use 'float.IsPositiveInfinity()' instead.}}
_ = f == System.Single.NegativeInfinity; // Noncompliant {{Do not check floating point equality with exact values, use 'float.IsNegativeInfinity()' instead.}}
}
}

namespace TestsWithTypeAliases
{
using DoubleAlias = Double;
Expand Down

0 comments on commit e45a03a

Please sign in to comment.