On Thu, Dec 17, 2015 at 10:38 AM, Dean Rasheed <dean.a.rash...@gmail.com> wrote:
> On 10 December 2015 at 20:02, Tom Lane <t...@sss.pgh.pa.us> wrote:
>> Robert Haas <robertmh...@gmail.com> writes:
>>> It seems to be a loss of 4 digits in every case I've seen.
>>
>> I wouldn't have a problem with, say, throwing in an extra DEC_DIGITS worth
>> of rscale in each of these functions so that the discrepancies tend to
>> favor more significant digits out, rather than fewer.  I don't know that
>> it's worth trying to guarantee that the result is never fewer digits than
>> before, and I certainly wouldn't want to make the rules a lot more complex
>> than what's there now.  But perhaps we could cover most cases easily.
>>
>
> Looking at this, it appears that those extra digits of precision for
> log(0.5) in the old code are an anomaly that only occurs for a certain
> range of inputs. According to the code comments these functions
> intentionally output at least around 16 significant digits (or more if
> the input has greater precision), so that they output at least the
> precision of floating point. For example, in both 9.5 and HEAD:
>
> select exp(5::numeric);
>         exp
> --------------------
>  148.41315910257660
>
> select exp(0.5::numeric);
>         exp
> --------------------
>  1.6487212707001281
>
> select ln(5::numeric);
>          ln
> --------------------
>  1.6094379124341004
>
> select ln(0.5::numeric);
>          ln
> ---------------------
>  -0.6931471805599453
>
> select power(0.5::numeric, 0.4::numeric);
>        power
> --------------------
>  0.7578582832551990
>
>
> However, the old log() code would occasionally output 4 more digits
> than that, due to it's mis-estimation of the result weight, which was
> used to determine the output scale. So, for example, in 9.5:
>
> select log(0.0005::numeric);
>          log
> ---------------------
>  -3.3010299956639812
>
> select log(0.005::numeric);
>          log
> ---------------------
>  -2.3010299956639812
>
> select log(0.05::numeric);
>            log
> -------------------------
>  -1.30102999566398119521
>
> select log(0.5::numeric);
>            log
> -------------------------
>  -0.30102999566398119521
>
> select log(5::numeric);
>           log
> ------------------------
>  0.69897000433601880479
>
> select log(50::numeric);
>         log
> --------------------
>  1.6989700043360188
>
> select log(500::numeric);
>         log
> --------------------
>  2.6989700043360188
>
> i.e., for a certain range of inputs the result precision jumps from 16
> to 20 digits after the decimal point, whereas in HEAD the precision of
> the results is more consistent across the range:
>
> select log(0.0005::numeric);
>          log
> ---------------------
>  -3.3010299956639812
>
> select log(0.005::numeric);
>          log
> ---------------------
>  -2.3010299956639812
>
> select log(0.05::numeric);
>          log
> ---------------------
>  -1.3010299956639812
>
> select log(0.5::numeric);
>          log
> ---------------------
>  -0.3010299956639812
>
> select log(5::numeric);
>         log
> --------------------
>  0.6989700043360188
>
> select log(50::numeric);
>         log
> --------------------
>  1.6989700043360188
>
> select log(500::numeric);
>         log
> --------------------
>  2.6989700043360188
>
>
> With other inputs, the actual number of significant digits can vary
> between 16 and 17, but it's generally better behaved than the old
> code, even though it sometimes produces fewer digits. I think it ought
> to be sufficient to release note that the number of digits returned by
> these functions may have changed, in addition to the results being
> more accurate.

Thanks for the additional explanation.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to