On 2/5/21 4:06 AM, Vladimir Sementsov-Ogievskiy wrote: >>> - /* >>> - * Values near UINT64_MAX overflow to 2**64 when converting to >>> double >>> - * precision. Compare against the maximum representable double >>> precision >>> - * value below 2**64, computed as "the next value after 2**64 >>> (0x1p64) in >>> - * the direction of 0". >>> - */ >>> - if ((val * mul > nextafter(0x1p64, 0)) || val < 0) { >>> + if (val > UINT64_MAX / mul) { >> >> Hmm, do we care about: >> 15.9999999999999999999999999999E >> where the fractional portion becomes large enough to actually bump our >> sum below to 16E which indeed overflows? Then again, we rejected a >> fraction of 1.0 above, and 0.9999999999999999999999999999 parses to 1.0 >> due to rounding. >> Maybe it's just worth a good comment why the overflow check here works >> without consulting fraction. > > worth a good comment, because I don't follow :) > > If mul is big enough and fraction=0.5, why val*mul + fraction*mul will > not overflow?
When mul is a power of 2, we know that fraction*mul does not change the number of significant bits, but merely moves the exponent, so starting with fraction < 1.0, we know fraction*mul < mul. But when @unit is 1000, there is indeed a rare possibility that the multiplication will cause an inexact answer that will trigger rounding, so we could end up with fraction*mul == mul. So I'm not yet 100% confident that there is no possible combination where we can't cause an overflow to result in val*mul + (uint64_t)(fraction*mul) resulting in 0 instead of UINT64_MAX, and I think I will have to tighten this code up for v2. > > Also, if we find '.' in the number, why not just reparse the whole > number with qemu_strtod_finite? And don't care about 1.0? Reparsing the whole number loses precision. Since we already have a 64-bit precise integer, why throw it away? > >> >>> retval = -ERANGE; >>> goto out; >>> } >>> - *result = val * mul; >>> + *result = val * mul + (uint64_t) (fraction * mul); >>> retval = 0; >>> >>> out: > > -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org