Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8e26b86

Browse files
committed
Fix corner-case loss of precision in numeric_power().
This fixes a loss of precision that occurs when the first input isvery close to 1, so that its logarithm is very small.Formerly, during the initial low-precision calculation to estimate theresult weight, the logarithm was computed to a local rscale that wascapped to NUMERIC_MAX_DISPLAY_SCALE (1000). However, the base may beas close as 1e-16383 to 1, hence its logarithm may be as small as1e-16383, and so the local rscale needs to be allowed to exceed 16383,otherwise all precision is lost, leading to a poor choice of rscalefor the full-precision calculation.Fix this by removing the cap on the local rscale during the initiallow-precision calculation, as we already do in the full-precisioncalculation. This doesn't change the fact that the initial calculationis a low-precision approximation, computing the logarithm to around 8significant digits, which is very fast, especially when the base isvery close to 1.Patch by me, reviewed by Alvaro Herrera.Discussion:https://postgr.es/m/CAEZATCV-Ceu%2BHpRMf416yUe4KKFv%3DtdgXQAe5-7S9tD%3D5E-T1g%40mail.gmail.com
1 parentae25435 commit8e26b86

File tree

3 files changed

+12
-1
lines changed

3 files changed

+12
-1
lines changed

‎src/backend/utils/adt/numeric.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10227,9 +10227,13 @@ power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
1022710227
*/
1022810228
ln_dweight=estimate_ln_dweight(base);
1022910229

10230+
/*
10231+
* Set the scale for the low-precision calculation, computing ln(base) to
10232+
* around 8 significant digits. Note that ln_dweight may be as small as
10233+
* -SHRT_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE here.
10234+
*/
1023010235
local_rscale=8-ln_dweight;
1023110236
local_rscale=Max(local_rscale,NUMERIC_MIN_DISPLAY_SCALE);
10232-
local_rscale=Min(local_rscale,NUMERIC_MAX_DISPLAY_SCALE);
1023310237

1023410238
ln_var(base,&ln_base,local_rscale);
1023510239

‎src/test/regress/expected/numeric.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2420,6 +2420,12 @@ select coalesce(nullif(0.9999999999 ^ 23300000000000, 0), 0) as rounds_to_zero;
24202420
0
24212421
(1 row)
24222422

2423+
select round(((1 - 1.500012345678e-1000) ^ 1.45e1003) * 1e1000);
2424+
round
2425+
----------------------------------------------------------
2426+
25218976308958387188077465658068501556514992509509282366
2427+
(1 row)
2428+
24232429
-- cases that used to error out
24242430
select 0.12 ^ (-25);
24252431
?column?

‎src/test/regress/sql/numeric.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,7 @@ select 1.2 ^ 345;
11141114
select0.12 ^ (-20);
11151115
select1.000000000123 ^ (-2147483648);
11161116
select coalesce(nullif(0.9999999999 ^23300000000000,0),0)as rounds_to_zero;
1117+
select round(((1-1.500012345678e-1000) ^1.45e1003)* 1e1000);
11171118

11181119
-- cases that used to error out
11191120
select0.12 ^ (-25);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp