Skip to content

Fix HistoStats in GaudiUtils to prevent floating point exceptions due to 'bad' return values

The histogram statistics printing utility HistoStats.cpp in GaudiUtils defines the follow default 'bad' value

const double s_bad      = -1 * std::numeric_limits<double>::max() ;

which is used in the various methods when the calculations cannot be performed for whatever reason.

The problem with this is it leads to floating point exceptions when subsequent calculations are performed. For example in HistoTableFormat.cpp

  % ( 100 * HistoStats::overflowEntriesFracErr   ( histo ) ) // 22) error on 21

This generates an overflow FPE when overflowEntriesFracErr returns s_bad, as this value cannot be multiplied by 100.

This MR proposes the follow fix, which is to change the 'bad' value to something smaller than the minimum possible value a double can represent

  const double s_bad      = std::numeric_limits<float>::lowest() ;

So -3.40282e+38 instead of -1.79769e+308 ... My assertion is, as far as satisfying the requirement of a 'bad' value, either is good enough, and by using the float value subsequent calculations performed in double precision are safe.

Of course, it does not have to be std::numeric_limits<float>::lowest(). Any large negative value, -1e50, -1e100, whatever serves the same purpose...

I have also made a number of other small cleanups, to prevent type conversions (to double) until absolutely required, to allow some checks to be performed on the original native types (sometimes int).

Merge request reports