On Mon, 12 Aug 2024 at 16:17, Joel Jacobson <joel@compiler.org> wrote:
>
> On Mon, Aug 12, 2024, at 17:14, Joel Jacobson wrote:
> > The case found with the smallest rscale adjustment was this one:
> > -[ RECORD 1 ]------+--------------------------------
> > var1 | 0.0000000000009873307197037692
> > var2 | 0.426697279270850
> > rscale_adjustment | -15
> > expected | 0.0000000000004212913318381285
> > numeric_mul_rscale | 0.0000000000004212913318381284
> > diff | -0.0000000000000000000000000001
>
Hmm, interesting example. There will of course always be cases where
the result isn't exact, but HEAD does produce the expected result in
this case, and the intention is to always produce a result at least as
accurate as HEAD, so it isn't working as expected.
Looking more closely, the problem is that to fully compute the
required guard digits, it is necessary to compute at least one extra
output base-NBASE digit, because the product of base-NBASE^2 digits
contributes to the next base-NBASE digit up. So instead of
maxdigitpairs = (maxdigits + 1) / 2;
we should do
maxdigitpairs = maxdigits / 2 + 1;
Additionally, since maxdigits is based on res_weight, we should
actually do the res_weight adjustments for odd-length inputs before
computing maxdigits. (Otherwise we're actually computing more digits
than strictly necessary for odd-length inputs, so this is a minor
optimisation.)
Updated patch attached, which fixes the above example and all the
other differences produced by your test. I think, with a little
thought, it ought to be possible to produce examples that round
incorrectly in a more systematic (less brute-force) way. It should
then be possible to construct examples where the patch differs from
HEAD, but hopefully only by being more accurate, not less.
Regards,
Dean