Skip to content

NET-3443 Fix S1940 FP: for floating point numbers that can be NaN "!(a <= b)" is not the same as "a > b" #9779

Closed

Description

@tobiass-sdl

Description

Not sure if this is a FP in the strong sense but the "why is this an issue" text should at least clearly state that the suggested "fix" behaves differently than the original code if a or b is NaN.

public static bool Foo(ReadOnlySpan<double> a, ReadOnlySpan<double> b)
{
   for (; i < a.Length; ++i)
   {
      if (!(a[i] <= b[i])) return false;
   }

   return true;
}

we have several places in our code base that intentionally invert the result of a floating point comparison. Applying the suggestion to remove the invert would cause bugs.

Obviously the solution on our side is to double check that we have unittests that protect against blind application of the so called fix.

Reproducer

public static bool Foo(ReadOnlySpan<double> a, ReadOnlySpan<double> b)
{
   for (; i < a.Length; ++i)
   {
      if (!(a[i] <= b[i])) return false;
   }

   return true;
}

Product and Version

Sonarqube server, Data Center Edition v2025.1 (102418)

Activity

  1. jilles-sg commented on Dec 23, 2025

    @jilles-sg

    Agreed, this kind of thing may cause bugs when people "fix" issues too quickly.

    I reported a similar issue for JavaScript a while ago in https://community.sonarsource.com/t/s1940-no-inverted-boolean-check-suggests-breaking-changes-for-floating-point/128556 but in C# it is a little easier because types like integers, decimal, DateOnly, DateTime, DateTimeOffset and TimeOnly have comparison operators that behave normally. On the other hand, not only float and double but also Half and the proposed Decimal32, Decimal64 and Decimal128 have NaN. It is also somewhat likely that custom operator implementations have bugs with values like default.

    I think restricting the rule to types with "well-behaved" comparison operators would yield a still useful rule that can safely be applied.

  2. changed the title [-]Fix S1940 FP: for floating point numbers that can be NaN "!(a <= b)" is not the same as "a > b"[/-] [+]NET-3443 Fix S1940 FP: for floating point numbers that can be NaN "!(a <= b)" is not the same as "a > b"[/+] on Mar 19, 2026
  3. github-actions commented on Mar 19, 2026

    @github-actions
    Contributor

    Internal ticket NET-3443

  4. alex-meseldzija-sonarsource commented on Mar 19, 2026

    @alex-meseldzija-sonarsource
    Contributor

    Hi @tobiass-sdl thanks for the report,

    I agree that this is an FP, and the fix is super misleading.

    I've created a ticket to add an exception for types that can be NaN, currently:

    • System.Half
    • System.Single
    • System.Double
    • System.Runtime.InteropService.NFloat
  5. alex-meseldzija-sonarsource commented on Apr 14, 2026

    @alex-meseldzija-sonarsource
    Contributor

    This has been fixed in our 10.22 release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    False PositiveRule IS triggered when it shouldn't be.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions