All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.l10n.py.rules.python.S6727.html Maven / Gradle / Ivy

There is a newer version: 4.23.0.17664
Show newest version

This rule raises an issue when math.isclose is used to compare values against 0 without providing the abs_tol parameter.

Why is this an issue?

Comparing float values for equality directly is not reliable and should be avoided, due to the inherent imprecision in the binary representation of floating point numbers. Such comparison is reported by {rule:python:S1244}.

One common solution to this problem is to use the math.isclose function to perform the comparison. Behind the scenes, the math.isclose function uses a tolerance value (also called epsilon) to define an acceptable range of difference between two floats. A tolerance value may be relative (based on the magnitude of the numbers being compared) or absolute.

Using a relative tolerance would be equivalent to:

def isclose_relative(a, b, rel_tol=1e-09):
    diff = abs(a - b)
    max_diff = rel_tol * max(abs(a), abs(b))
    return diff <= max_diff

Using an absolute tolerance is equivalent to:

def isclose_absolute(a, b, abs_tol=1e-09):
    diff = abs(a - b)
    return diff <= abs_tol

The math.isclose method uses both relative and absolute tolerances and can be approximated as:

def is_close(a, b, rel_tol=1e-09, abs_tol=0.0):
    diff = abs(a - b)
    max_diff = max(rel_tol * max(abs(a), abs(b)), abs_tol)
    return diff <= max_diff

Whenever comparing values that are close to 0, the value of the relative tolerance may be too small to overcome the imprecision introduced by floating-point arithmetic. It is therefore important to rely on an absolute tolerance in this case.

When using math.isclose, the absolute tolerance is defined through the parameter abs_tol. By default, the value of this parameter is 0.0. Therefore, using math.isclose to compare values against zero without providing this parameter is equivalent to a strict equality check, which is likely not intended.

Exceptions

Note that similar methods from different libraries may behave differently. Notably, numpy.isclose has a default absolute tolerance of 1e-08. No issue will be reported in this case. However, to ensure consistency and intentionality, it is recommended to always set the tolerance values.

How to fix it

To fix this issue, make sure to provide the abs_tol argument to the math.isclose function whenever comparing values against zero. If a strict equality check is intended, consider using the equality operator or providing 0 as the abs_tol parameter to make the intention clear.

Code examples

Noncompliant code example

import math
def foo(a):
    return math.isclose(a, 0)  # Noncompliant: the default absolute tolerance is 0.0

Compliant solution

import math
def foo(a):
    return math.isclose(a, 0, abs_tol=1e-09)  # Compliant

Resources

Documentation

Related rules

  • {rule:python:S1244}: Floating point numbers should not be tested for equality




© 2015 - 2024 Weber Informatics LLC | Privacy Policy