Numerical Stability
Tolerance Compare
Near Enough Values
Floating-point checks usually compare a difference against a tolerance instead of exact equality.
Program
Play the program to tighten or loosen the tolerance.
tolerance_compare.f90
Replay: real traced execution (multi-file project)
program tolerance_compare_demo
implicit none
real :: expected
real :: observed
real :: tolerance
real :: difference
integer :: passed
expected = 10.0
observed = 9.9
tolerance = 0.20
difference = abs(expected - observed)
passed = 0
if (difference <= tolerance) passed = 1
print '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passed
end program tolerance_compare_demo
program tolerance_compare_demo
implicit none
real :: expected
real :: observed
real :: tolerance
real :: difference
integer :: passed
expected = 10.0
observed = 9.9
tolerance = 0.05
difference = abs(expected - observed)
passed = 0
if (difference <= tolerance) passed = 1
print '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passed
end program tolerance_compare_demo
program tolerance_compare_demo
implicit none
real :: expected
real :: observed
real :: tolerance
real :: difference
integer :: passed
expected = 10.0
observed = 9.9
tolerance = 0.50
difference = abs(expected - observed)
passed = 0
if (difference <= tolerance) passed = 1
print '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passed
end program tolerance_compare_demo
expected ← 10.0
9expected = 10.010observed = 9.9values this step10.0expectedobserved ← 9.9
9expected = 10.010observed = 9.911tolerance = 0.20values this step9.9observedtolerance ← 0.20
10observed = 9.911tolerance = 0.2012difference = abs(expected - observed)values this step0.20tolerancedifference ← 0.10
11tolerance = 0.2012difference = abs(expected - observed)13passed = 0values this step0.10difference10.0expected9.9observedpassed ← 0
12difference = abs(expected - observed)13passed = 014if (difference <= tolerance) passed = 1values this step0passedpassed ← 1
13passed = 014if (difference <= tolerance) passed = 115print '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passedvalues this step1passed.true.difference <= toleranceprint '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passed
14 if (difference <= tolerance) passed = 115 print '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passed16end program tolerance_compare_demooutput0.10 0.20 1values this step0.10difference0.20tolerance1passed
expected ← 10.0
9expected = 10.010observed = 9.9values this step10.0expectedobserved ← 9.9
9expected = 10.010observed = 9.911tolerance = 0.05values this step9.9observedtolerance ← 0.05
10observed = 9.911tolerance = 0.0512difference = abs(expected - observed)values this step0.05tolerancedifference ← 0.10
11tolerance = 0.0512difference = abs(expected - observed)13passed = 0values this step0.10difference10.0expected9.9observedpassed ← 0
12difference = abs(expected - observed)13passed = 014if (difference <= tolerance) passed = 1values this step0passedif (difference <= tolerance) passed = 1
13passed = 014if (difference <= tolerance) passed = 115print '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passedvalues this step.false.difference <= toleranceprint '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passed
14 if (difference <= tolerance) passed = 115 print '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passed16end program tolerance_compare_demooutput0.10 0.05 0values this step0.10difference0.05tolerance0passed
expected ← 10.0
9expected = 10.010observed = 9.9values this step10.0expectedobserved ← 9.9
9expected = 10.010observed = 9.911tolerance = 0.50values this step9.9observedtolerance ← 0.50
10observed = 9.911tolerance = 0.5012difference = abs(expected - observed)values this step0.50tolerancedifference ← 0.10
11tolerance = 0.5012difference = abs(expected - observed)13passed = 0values this step0.10difference10.0expected9.9observedpassed ← 0
12difference = abs(expected - observed)13passed = 014if (difference <= tolerance) passed = 1values this step0passedpassed ← 1
13passed = 014if (difference <= tolerance) passed = 115print '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passedvalues this step1passed.true.difference <= toleranceprint '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passed
14 if (difference <= tolerance) passed = 115 print '(F0.2, 1X, F0.2, 1X, I0)', difference, tolerance, passed16end program tolerance_compare_demooutput0.10 0.50 1values this step0.10difference0.50tolerance1passed
difference
`abs(expected - observed)` measures the gap between values.
tolerance
The tolerance records how much difference is acceptable.
near comparison
The result passes when the difference is within tolerance.