You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[ntuple] Precision loss for big integer values #416
When reading RNTuple data, Int64/UInt64 values above Number.MAX_SAFE_INTEGER or below Number.MIN_SAFE_INTEGER lose precision because they're cast to Number in rntuple.mjs:
// FIXME: let process BigInt in the TTree::Drawobj[this.name]=Number(this.view.getBigInt64(this.o,LITTLE_ENDIAN));
The FIXME comment suggests this is known. Since Number and BigInt are distinct types in JS, would it make sense to return a BigInt only when the value doesn't fit in a safe integer, and a Number otherwise? Something like:
One can make extra argument for treeProcess function which let keep BigInt values.
So one get at least all values with TSelector correctly.
But processing in treeDraw is more complicated.
There one has several use-cases, and BigInt has to be handled separately.
Main problem there - use of BigInt in generic arithmetic expressions.
One cannot simply mix Number and BigInt - unfortunately.
Its unfortunate that there is no elegant way of processing BigInt and Number in JS. Here is a proposal for an extra convertBigInt argument to process rntupleDraw slightly different:
// in rntuple.mjsclassReaderItem{constructor(column,name,convertBigInt){this.column=null;this.name=name;this.id=-1;this.coltype=0;this.sz=0;this.simple=true;this.page=-1;// current page for the readingthis.convertBigInt=convertBigInt;
...
case kIndex64:
this.func=function(obj){constval=this.view.getBigInt64(this.o,LITTLE_ENDIAN)obj[this.name]=this.convertBigInt ? Number(val) : val;this.shift_o(8);};this.sz=8;break;
case kUInt64:
this.func=function(obj){constval=this.view.getBigUint64(this.o,LITTLE_ENDIAN)obj[this.name]=this.convertBigInt ? Number(val) : val;this.shift_o(8);};this.sz=8;break;
...
}asyncfunctionrntupleProcess(rntuple,selector,args={}){const{convertBigInt =false, ...restArgs}=args;
...
functionaddColumnReadout(column,tgtname){constitem=newReaderItem(column,tgtname,convertBigInt);item.assignReadFunc();handle.columns.push(item);returnitem;}...}asyncfunctionrntupleDraw(rntuple,args){if(isStr(args))args={expr: args};elseif(!isObject(args))args={};args.SelectorClass=TDrawSelectorTuple;args.processFunction=rntupleProcess;args.convertBigInt=true;treeDrawCall=true;returnreadHeaderFooter(rntuple).then(builder=>{returnbuilder ? treeDraw(rntuple,args) : null;});}
Activity
linev commentedon Aug 13, 2026
One can make extra argument for
treeProcessfunction which let keepBigIntvalues.So one get at least all values with
TSelectorcorrectly.But processing in
treeDrawis more complicated.There one has several use-cases, and
BigInthas to be handled separately.Main problem there - use of
BigIntin generic arithmetic expressions.One cannot simply mix Number and BigInt - unfortunately.
undefined-panda commentedon Aug 14, 2026
Its unfortunate that there is no elegant way of processing
BigIntandNumberin JS. Here is a proposal for an extraconvertBigIntargument to processrntupleDrawslightly different:Would that be suitable?
linev commentedon Aug 14, 2026
But probably something like
args.preserveBigInt. Then defaultfalseorundefinedwill untouch current behavior.linev commentedon Aug 14, 2026
Fixed in #418