Re: Numeric x^y for negative x - Mailing list pgsql-hackers

From Dean Rasheed
Subject Re: Numeric x^y for negative x
Date
Msg-id CAEZATCUoVETahg892Qu3umjXX-V8J-F2xqQqunxckd5Se8KLyg@mail.gmail.com
Whole thread Raw
In response to Numeric x^y for negative x  (Dean Rasheed <dean.a.rasheed@gmail.com>)
Responses Re: Numeric x^y for negative x  (Dean Rasheed <dean.a.rasheed@gmail.com>)
List pgsql-hackers
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



pgsql-hackers by date:

Previous
From: Andrew Dunstan
Date:
Subject: Re: PXGS vs TAP tests
Next
From: vignesh C
Date:
Subject: Re: Column Filtering in Logical Replication