Skip to content

Tolerant comparison of real numbers #327

Open
@arjenmarkus

Description

@arjenmarkus

I have the source for a set of comparison functions and other functions such as floor and ceil that take into account that real numbers are not as well-behaved as, say, integers, by taking a margin into account. The source comes from Skip Knoble, once quite active on comp.lang.fortran, and builds on work by Hindmarsh and others.

Is this something useful for stdlib? The source needs to be updated to the current standard, but I can do that :).

Activity

epagone

epagone commented on Feb 26, 2021

@epagone

Personally, I would be very interested in that. The naive approach that I currently use in my codes is the following:

elemental logical function eqreal(real1, real2)
    real(wp), intent(in) :: real1, real2
    eqreal = abs(real1 - real2) < spacing( max( abs(real1), abs(real2) ) )
end function eqreal

I would be curious to learn what a proper approach would be.

arjenmarkus

arjenmarkus commented on Feb 26, 2021

@arjenmarkus
MemberAuthor

I am not sure if there is a proper approach ;). The best I can think of is a well-chosen tolerance and that may actually be dependent on the application. The code I was referring predates Fortran 90, by the way, but it is definitely worth considering, if only because it will provide some common ground based on much prior work.

ivan-pi

ivan-pi commented on Feb 26, 2021

@ivan-pi
Member

I think this is a partial duplicate of #145.

We can keep this issue open for the well-behaved floor and ceil functions, but I would suggest changing the title in that case.

arjenmarkus

arjenmarkus commented on Feb 26, 2021

@arjenmarkus
MemberAuthor
jvdp1

jvdp1 commented on Feb 26, 2021

@jvdp1
Member

Is this something useful for stdlib?

I think it is indeed something for stdlib. It could even be used inside stdlib for the different tests with real values (and for which we already got multiple issues/discussions).

arjenmarkus

arjenmarkus commented on Mar 1, 2021

@arjenmarkus
MemberAuthor

I attach the original source code eps_f90.txt - I have not take the opportunity yet to convert it to a modern package, so it is really old-school :). However, the output from the program may be of interest to give better insight:

EPS= 0.22204460D-15 3CB0000000000000, EPS3= 0.66613381D-15 3CC8000000000000
X=1.D0/ 49 , Y=X* 49 , Z=1.D0
Y= 0.99999999999999989 Z= 1.0000000000000000
X=3F94E5E0A72F0539 Y=3FEFFFFFFFFFFFFF Z=3FF0000000000000
Fuzzy Comparisons: Y<>Z
but TEQ(Y,Z) is .TRUE.
That is, Y is computationally equal to Z.

X=0.11D0, Y=X*11.D0-X-0.1D0, Z=1.D0
X= 0.11000000000000000 Y= 0.99999999999999989 Z= 1.0000000000000000
X=3FBC28F5C28F5C29 Y=3FEFFFFFFFFFFFFF Z=3FF0000000000000
Fuzzy FLOOR/CEIL: Y<>Z
but TFLOOR(Y,EPS3)=TCEIL(Y,EPS3)=Z.
That is, TFLOOR/TCEIL return exact whole numbers.

certik

certik commented on Mar 24, 2021

@certik
Member

Some feedback from the Fortran call:

awvwgk

awvwgk commented on Mar 24, 2021

@awvwgk
Member

What about an API similar to pytest.approx? This allows to create an object, which holds the tolerance and overloads the usual comparison operators in a convenient way.

ghost

ghost commented on Mar 24, 2021

@ghost

It's called isClose in the D language.

Interface
isClose(lhs, rhs, maxRelDiff, maxAbsDiff)

Documentation
https://dlang.org/phobos/std_math.html#.isClose

Implementation
https://github.com/dlang/phobos/blob/stable/std/math.d#L8847

ghost

ghost commented on May 13, 2021

@ghost

GNU GSL also has this functionality in the function gsl_fcmp.

Interface
int gsl_fcmp (const double x1, const double x2, const double epsilon);

Documentation
https://www.gnu.org/software/gsl/doc/html/math.html#approximate-comparison-of-floating-point-numbers

Implementation (License: GPL)
https://git.savannah.gnu.org/cgit/gsl.git/tree/sys/fcmp.c

added
topic: utilitiescontainers, strings, files, OS/environment integration, unit testing, assertions, logging, ...
topic: mathematicslinear algebra, sparse matrices, special functions, FFT, random numbers, statistics, ...
and removed
topic: utilitiescontainers, strings, files, OS/environment integration, unit testing, assertions, logging, ...
on Sep 18, 2021
dalon-work

dalon-work commented on Sep 25, 2021

@dalon-work

This blog post discuss 4 different ways to compare floating-point numbers: https://codingnest.com/the-little-things-comparing-floating-point-numbers/

Beliavsky

Beliavsky commented on Apr 5, 2025

@Beliavsky
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

    topic: mathematicslinear algebra, sparse matrices, special functions, FFT, random numbers, statistics, ...

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @certik@arjenmarkus@dalon-work@jvdp1@epagone

        Issue actions

          Tolerant comparison of real numbers · Issue #327 · fortran-lang/stdlib