Rounding in TH1F when using weights


Executing the following script:

#include <iostream>

#include "TH1F.h"
#include "TRandom.h"

void wtest() {
   TH1F* h1 = new TH1F("h1","",1,-0.5,0.5);
   TH1F* h2 = new TH1F("h2","",10,0,10);

   TRandom* rnd = new TRandom();

   Double_t W=0.0;
   Int_t N=1000000;
   for (Int_t event=1; event<=N; event++) {
      Double_t w=2*rnd->Rndm();
      W+=w;
      h1->Fill(0.0,w);
      Double_t x = 10*rnd->Rndm();
      
      h2->Fill(x,w);
   }

   Double_t N1=h1->GetSumOfWeights();
   Double_t N2=h2->GetSumOfWeights();
   
   std::cout<<"N1="<<N1<<" N2="<<N2<<" W="<<W<<" N1-n2="<<N1-N2<<" W-N1="
	    <<W-N1<<" W-N2="<<W-N2<<std::endl;
   
}

Gives the following output:

[shtol@sndgpc2 root]$ root -l wtest.C+
root [0] 
Processing wtest.C+...
Info in <TUnixSystem::ACLiC>: creating shared library /sweet/home/shtol/root/lib/wtest_C.so
Warning in cling::IncrementalParser::CheckABICompatibility():
  Possible C++ standard library mismatch, compiled with __GLIBCXX__ '20231218'
  Extraction of runtime standard library version was: '20240719'
N1=1.00005e+06 N2=1.00004e+06 W=1.00004e+06 N1-n2=10.0625 W-N1=-10.3748 W-N2=-0.312336

So, sum of weights of all events i different for different histograms (and depends on number of bins). Using TH1D instead if TH1F fixes this problem, all differences becomes zero.

ROOT Version: 6.32.06
Platform: AlmaLinux 9.5 (Teal Serval)
Compiler: c++ (GCC) 11.4.1 20231218 (Red Hat 11.4.1-3)


Yes all your number are double and your histogram is float. The precision issue you encounter is normal. Why don’t you use TH1D ?

Historically we used mainly TH1F - without weights there are no difference. Now I will use TH1D and advice all colleages to do the same.

1 Like

TH1F: even without weights, just calling Fill(), if one of your bins contains more than 1e7 entries, you will start seeing saturation problems (Fill has no effect):

See note on ‘maximum integer content’ of ROOT: TH1 Class Reference

1 Like