Skip to content

Commit 3959abc

Browse files
committed
[hist] Apply suggestions by Jonas R.
Implement suggestions by Jonas R. to make FindFixBin more robust to numerical errors
1 parent 07396f9 commit 3959abc

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

hist/hist/src/TAxis.cxx

+14-13
Original file line numberDiff line numberDiff line change
@@ -404,20 +404,21 @@ Int_t TAxis::DoFindFixBin(Double_t x) const
404404
{
405405
int bin = 0;
406406
if (!fXbins.fN) { //*-* fix bins
407-
bin = 1 + int (fNbins * (x-fXmin)/(fXmax-fXmin) );
408-
// apply correction when x is at the bin edge value
409-
// (computed as in GetBinLowEdge) a numerical error in the
410-
// above division can cause a migration in a neighbour bin.
411-
double binwidth = (fXmax - fXmin) / Double_t(fNbins);
412-
double upEdge = fXmin + (bin) * binwidth;
413-
double lowEdge = fXmin + (bin - 1) * binwidth;
414-
if (upEdge <= x) bin += 1;
415-
if (lowEdge > x) bin -= 1;
416-
} else { //*-* variable bin sizes
417-
//for (bin =1; x >= fXbins.fArray[bin]; bin++);
418-
bin = 1 + TMath::BinarySearch(fXbins.fN,fXbins.fArray,x);
407+
// shift x and fXmax by fXmin:
408+
x = x - fXmin;
409+
const double b = fXmax - fXmin;
410+
const double s = fNbins * x; // scaled version of x
411+
double m = std::floor(s / b);
412+
// iterative correction in case of floating point errors due to floating point division
413+
while (m * b >= s)
414+
m = m - 1;
415+
while ((m + 1) * b < s)
416+
m = m + 1;
417+
return 1 + Int_t(m);
418+
} else { //*-* variable bin sizes
419+
// for (bin =1; x >= fXbins.fArray[bin]; bin++);
420+
return 1 + TMath::BinarySearch(fXbins.fN, fXbins.fArray, x);
419421
}
420-
return bin;
421422
}
422423

423424
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)