diff --git a/hist/hist/src/TAxis.cxx b/hist/hist/src/TAxis.cxx index 871a7c80ac230..1404d4d18c586 100644 --- a/hist/hist/src/TAxis.cxx +++ b/hist/hist/src/TAxis.cxx @@ -404,20 +404,21 @@ Int_t TAxis::DoFindFixBin(Double_t x) const { int bin = 0; if (!fXbins.fN) { //*-* fix bins - bin = 1 + int (fNbins * (x-fXmin)/(fXmax-fXmin) ); - // apply correction when x is at the bin edge value - // (computed as in GetBinLowEdge) a numerical error in the - // above division can cause a migration in a neighbour bin. - double binwidth = (fXmax - fXmin) / Double_t(fNbins); - double upEdge = fXmin + (bin) * binwidth; - double lowEdge = fXmin + (bin - 1) * binwidth; - if (upEdge <= x) bin += 1; - if (lowEdge > x) bin -= 1; - } else { //*-* variable bin sizes - //for (bin =1; x >= fXbins.fArray[bin]; bin++); - bin = 1 + TMath::BinarySearch(fXbins.fN,fXbins.fArray,x); + // shift x and fXmax by fXmin: + x = x - fXmin; + const double b = fXmax - fXmin; + const double s = fNbins * x; // scaled version of x + double m = std::floor(s / b); + // iterative correction in case of floating point errors due to floating point division + while (m * b >= s) + m = m - 1; + while ((m + 1) * b < s) + m = m + 1; + return 1 + Int_t(m); + } else { //*-* variable bin sizes + // for (bin =1; x >= fXbins.fArray[bin]; bin++); + return 1 + TMath::BinarySearch(fXbins.fN, fXbins.fArray, x); } - return bin; } ////////////////////////////////////////////////////////////////////////////////