Skip to content

Commit 0736fc1

Browse files
committed
Clarify the choice of rscale in numeric_sqrt().
Improve the comment explaining the choice of rscale in numeric_sqrt(), and ensure that the code works consistently when other values of NBASE/DEC_DIGITS are used. Note that, in practice, we always expect DEC_DIGITS == 4, and this does not change the computation in that case. Joel Jacobson and Dean Rasheed Discussion: https://postgr.es/m/06712c29-98e9-43b3-98da-f234d81c6e49%40app.fastmail.com
1 parent 9a84f29 commit 0736fc1

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

src/backend/utils/adt/numeric.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3693,8 +3693,21 @@ numeric_sqrt(PG_FUNCTION_ARGS)
36933693

36943694
init_var(&result);
36953695

3696-
/* Assume the input was normalized, so arg.weight is accurate */
3697-
sweight = (arg.weight + 1) * DEC_DIGITS / 2 - 1;
3696+
/*
3697+
* Assume the input was normalized, so arg.weight is accurate. The result
3698+
* then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
3699+
* digits before the decimal point. When DEC_DIGITS is even, we can save
3700+
* a few cycles, since the division is exact and there is no need to round
3701+
* towards negative infinity.
3702+
*/
3703+
#if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
3704+
sweight = arg.weight * DEC_DIGITS / 2 + 1;
3705+
#else
3706+
if (arg.weight >= 0)
3707+
sweight = arg.weight * DEC_DIGITS / 2 + 1;
3708+
else
3709+
sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
3710+
#endif
36983711

36993712
rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
37003713
rscale = Max(rscale, arg.dscale);

0 commit comments

Comments
 (0)