On 3/15/21 4:10 AM, Philippe Mathieu-Daudé wrote: > On 3/15/21 12:48 AM, Richard Henderson wrote: >> Use fma to simulatneously scale and round up fraction. > > "simultaneously" > >> The libm function will always return a properly rounded double precision >> value, which will eliminate any extra precision the x87 co-processor may >> give us, which will keep the output predictable vs other hosts. >> >> Adding DBL_EPSILON while scaling should help with fractions like >> 12.345, where the closest representable number is actually 12.3449*. >> >> Signed-off-by: Richard Henderson <richard.hender...@linaro.org> >> --- >> util/cutils.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/util/cutils.c b/util/cutils.c >> index d89a40a8c3..f7f8e48a68 100644 >> --- a/util/cutils.c >> +++ b/util/cutils.c >> @@ -342,7 +342,7 @@ static int do_strtosz(const char *nptr, const char **end, >> if (val > (UINT64_MAX - ((uint64_t) (fraction * mul))) / mul) { > > Shouldn't we use fma() here too? ^^^^^^^^^^^^^^^^^^^^^^^^^^
Unlikely to make a difference in practice, but yes, consistency argues that we should perform the same computations. In fact, it may be worth factoring out the computation to be done once, instead of relying on the compiler to determine if fma() can undergo common subexpression elimination. > >> retval = -ERANGE; >> goto out; >> } >> - *result = val * mul + (uint64_t) (fraction * mul); >> + *result = val * mul + (uint64_t)fma(fraction, mul, DBL_EPSILON); >> retval = 0; >> >> out: >> > > -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org