Closed chrisj closed 2 months ago
This is the most minimal change that appears to fix the problem. It would give me a little more peace of mind if BigInt was used before the multiplication of vHigh *= trueBase
. BigInt is able to recover the true value but it's a little concerning.
92064593 * 0x100000000 = 395414416054550500
BigInt(395414416054550500) = 395414416054550528n
vHigh *= trueBase
is always exact since trueBase
is a power of two, so we are just adding to the exponent field.
However, I didn't think about the issue of rounding up for the subsequent division.
Ultimately it may make sense to eliminate Uint64 entirely and just use bigint in Neuroglancer now. But your fix looks good.
https://github.com/google/neuroglancer/blob/daf82f3ad4af2007e96faca35143cd5ec986bf60/src/util/uint64.ts#L105
if vHigh >
Number.MAX_SAFE_INTEGER / 0x100000000
vHigh *= trueBase;
will exceed Number.MAX_SAFE_INTEGER.Math.floor(vHigh / lowBase)
will then start to return whole numbers when the fraction is very close to 0 or 1. When it is due to it being 1, javascript rounds up which then causes the floor operation to fail. BigInt safely handle the division + floor operation.For example: base 3, low 0, high 92064593 92064593 * trueBase / 3486784401 = 113403746.99999998652053164327...