On Tue, 29 Jun 2021 at 12:08, Dean Rasheed <dean.a.rasheed@gmail.com> wrote:
>
> Numeric x^y is supported for x < 0 if y is an integer, but this
> currently fails if y is outside the range of an int32
>
I've been doing some more testing of this, and I spotted another
problem with numeric_power().
This is what happens when raising 0.9999999999 to increasingly large
powers, which should decrease to zero:
exp 0.9999999999^exp
10000000000 0.3678794411530483
100000000000 0.[4 zeros]4539992973978489
1000000000000 0.[43 zeros]3720075957420456
10000000000000 0.[434 zeros]5075958643751518
20000000000000 0.[868 zeros]2576535615307575
21000000000000 0.[912 zeros]9584908195943232
22000000000000 0.[955 zeros]3565658653381070
23000000000000 0.[998 zeros]13
23100000000000 0.[1000 zeros]
23200000000000 0.[1000 zeros]
23300000000000 1.[1000 zeros] *** WRONG ***
30000000000000 1.[1000 zeros] *** WRONG ***
40000000000000 1.[1000 zeros] *** WRONG ***
50000000000000 1.[1000 zeros] *** WRONG ***
60000000000000 1.[1000 zeros] *** WRONG ***
70000000000000 ERROR: value overflows numeric format
The cases where it returns 1 are a trivial logic bug in the
local_rscale calculation in power_var() -- when it computes
local_rscale from rscale and val, it needs to do so before clipping
rscale to NUMERIC_MAX_DISPLAY_SCALE, otherwise it ends up setting
local_rscale = 0, and loses all precision.
I also don't think it should be throwing an overflow error here. Some
code paths through numeric_power() catch cases that would underflow,
and return zero instead, but not all cases are caught. There's a
similar overflow error with numeric_exp() for large negative inputs
(-5999 returns 0, but -6000 overflows).
It's arguable though that numeric power() and exp() (and mul() for
that matter) should never return 0 for finite non-zero inputs, but
instead should throw underflow errors, which would make them
compatible with their floating-point counterparts. I don't think
that's useful though, and it's more likely to break people's code for
no real benefit. No other numeric code throws underflow errors.
So I think we should just attempt to avoid all such overflow errors,
that are actually underflows, and return zero instead.
Regards,
Dean