@@ -404,20 +404,21 @@ Int_t TAxis::DoFindFixBin(Double_t x) const
404
404
{
405
405
int bin = 0 ;
406
406
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);
419
421
}
420
- return bin;
421
422
}
422
423
423
424
// //////////////////////////////////////////////////////////////////////////////
0 commit comments