Can I fill a TH1I with "false double"

Dear experts,

I wonder if I can fill a TH1I histogram with “false double”. Indeed I had integers values, and a double function return these integers (so I ends up with number which terminate with .000000…x), so I wonder if I can still fill a TH1I with this “false double” value?


sure you can. The “I” in “TH1I” does not mean you can only fill it with integers, it simply means maximum bin content is 2147483647, i.e. one integer per bin.

Dear Yus,
ok, thank you for your replay.

Of course if you fill a TH1I bin with a double (or float) then, when you get back the bin content, you will lose the digits after the dot:

root [0] TH1I *h = new TH1I("h","h",10 , 0, 10);
root [1] h->SetBinContent(3,3.14)
root [2] h->GetBinContent(3)
(Double_t) 3.00000

Dear Couet,

ok thank you, so why can’t we cast (for example) a TH1F into a TH1D then?


What do you really want to achieve, why would the cast be necessary? Just create the histogram with the desired type in the beginning.

Could it be that you were looking for polymorphism?

// only specify the concrete type TH1F/TH1D once when using new,
// use TH1* when it is independent of the concrete type.
TH1 *h = new TH1D(...); 

When you create a TH1I the internal vector used to store the bins is integer
When you create a TH1F the internal vector used to store the bins is float
When you create a TH1D the internal vector used to store the bins is double

In C++ when you assign a float or a double into an int then the digits after the dot are lost … obviously … it is the same here.

Dear Couet and behrenhoff,

for the “casting” question, I wanted to understand an answer that I got some time ago by a root expert who said [1], and which really surprised me, and this is the real reason why I posted this post, because I started to thing that maybe I can’t fill a TH1I with double etc… So I wanted to clear that, and I understood now that yes, I can cast a TH1F in a TH1D, right? and if yes, why [2] does not work.


“You cannot cast from a TH1D to a TH1F.”


root [0] TH1D *hd = new TH1D()
(TH1D *) 0x7f99ab768420
root [1] TH1F *hf = new TH1F()
(TH1F *) 0x7f99ad2f0750
root [2] hf->ClassName()
(const char *) "TH1F"
root [3] hf = (TH1F*)hd;
root [4] hf->ClassName()
(const char *) "TH1D"

It does not make sense to cast (see the answers in the post you mentioned). You should copy … also be aware of the truncation issue I mentionned.

No. What you are doing is “access to an object through a pointer of a different type”.

It is even worse than “It does not make sense to cast” because it is UB, so don’t do that! See

Dear experts,

ok, thank you for your answers.