It looks like FloatAlmostEqual function (itkMath.h) does rather similar thing twice, in particular if floats are not almost equal - subtract, abs, compare (first to epsilon, then unit of least precision), isn’t it? It is not wrong, but may be it could impact performance?

# itkMath FloatAlmostEqual question

**Niels_Dekker**(Niels Dekker) #2

I think this is intended. A pair of floating point numbers could have a large absolute difference, and still be considered “almost equal”:

```
EXPECT_TRUE(
itk::Math::FloatAlmostEqual(
1.7976931348623158e+308, // <== Which is DBL_MAX.
1.7976931348623156e+308 // <== Mind the last decimal digit!
));
```

In this case, the absolute difference is ~2.0e+292, while these two numbers only differ by one unit of least precision (ULP).

On the other hand, a pair of floating point numbers could have a large absolute ULP difference, and still be considered “almost equal”:

```
EXPECT_TRUE(
itk::Math::FloatAlmostEqual(
2.2250738585072014e-308, // <== Which is DBL_MIN.
0.0
));
```

My debugger tells me that DBL_MIN is 4503599627370496 ULPs apart from 0.0, yet these numbers could be considered almost equal, right?

That’s possible, of course. But do you have a specific application or image filter in mind, whose performance could be affected by this function?

**mihail.isakov**(mihail.isakov) #3

Thank you for explanation.

But do you have a specific application or image filter in mind, whose performance could be affected by this function?

```
./Modules/Numerics/Statistics/include/itkHistogramToTextureFeaturesFilter.hxx: if( Math::FloatAlmostEqual( pixelVarianceSquared, 0.0, 4, 2*NumericTraits<double>::epsilon() ) )
./Modules/Filtering/Thresholding/include/itkOtsuMultipleThresholdsCalculator.hxx: !Math::FloatAlmostEqual( maxVarBetween, varBetween, maxUlps) )
./Modules/Filtering/ImageFrequency/include/itkFrequencyBandImageFilter.hxx: if ( Math::FloatAlmostEqual(scalarFrequency, this->m_LowFrequencyThreshold) )
./Modules/Filtering/ImageFrequency/include/itkFrequencyBandImageFilter.hxx: if ( Math::FloatAlmostEqual(scalarFrequency, this->m_HighFrequencyThreshold) )
./Modules/Filtering/Path/include/itkPolyLineParametricPath.hxx: if ( input > endPoint || itk::Math::FloatAlmostEqual( input, endPoint ) )
./Modules/Filtering/FastMarching/include/itkFastMarchingImageFilterBase.hxx: if (itk::Math::FloatAlmostEqual<double>(cc, 0.0))
./Modules/Core/Common/include/itkVersor.hxx: if ( Math::FloatAlmostEqual<T>(vectorNorm, 0.0) )
./Modules/Core/Transform/include/itkBSplineTransform.hxx: if( Math::FloatAlmostEqual( index[j], maxLimit, 4 ) )
./Modules/Core/Transform/include/itkVersorRigid3DTransform.hxx: if (Math::FloatAlmostEqual<TParametersValueType>(norm, 0.0))
```

Edit: removed calls from tests

**Niels_Dekker**(Niels Dekker) #4

Interesting. I think you’re right: it seems to me that in some of these cases, the performance could be improved by doing something else than calling the current `FloatAlmostEqual`

function. For example, instead of `FloatAlmostEqual(x, 0.0)`

, I think I would prefer something like `abs(x) < DBL_MIN`

. But I haven’t had a close look yet at these particular cases.

**dzenanz**(Dženan Zukić) #6

You are right, in some cases `FloatAlmostEqual`

could be replaced by less general `std::abs(x)<epsilon`

. But as that case is checked first in `FloatAlmostEqual`

, and it should be in the predicted branch, the extra code in `FloatAlmostEqual`

should not matter. Of course, to test this assumption a change should be made and performance compared with and without the change.