Thread

Commits

  1. Fix numeric_power() when the exponent is INT_MIN.

  1. Bug in numeric_power() if exponent is INT_MIN

    Dean Rasheed <dean.a.rasheed@gmail.com> — 2021-01-04T17:24:08Z

    (Amusingly I only found this after discovering that Windows Calculator
    has a similar bug which causes it to crash if you try to raise a
    number to the power INT_MIN.)
    
    On my machine, numeric_power() loses all precision if the exponent is
    INT_MIN, though the actual failure mode might well be
    platform-dependent:
    
    SELECT n, 1.000000000123^n AS pow
      FROM (VALUES (-2147483647), (-2147483648), (-2147483649)) AS v(n);
          n      |        pow
    -------------+--------------------
     -2147483647 | 0.7678656557347558
     -2147483648 | 1.0000000000000000
     -2147483649 | 0.7678656555458609
    (3 rows)
    
    The issue is in this line from power_var_int():
    
        sig_digits += (int) log(Abs(exp)) + 8;
    
    because "exp" is a signed int, so Abs(exp) leaves INT_MIN unchanged.
    The most straightforward fix is to use fabs() instead, so that "exp"
    is cast to double *before* the absolute value is taken, as in the
    attached patch.
    
    This code was added in 7d9a4737c2, which first appeared in PG 9.6, so
    barring objections, I'll push and back-patch this fix that far.
    
    Regards,
    Dean
    
  2. Re: Bug in numeric_power() if exponent is INT_MIN

    Tom Lane <tgl@sss.pgh.pa.us> — 2021-01-04T17:59:22Z

    Dean Rasheed <dean.a.rasheed@gmail.com> writes:
    > The issue is in this line from power_var_int():
    >     sig_digits += (int) log(Abs(exp)) + 8;
    > because "exp" is a signed int, so Abs(exp) leaves INT_MIN unchanged.
    > The most straightforward fix is to use fabs() instead, so that "exp"
    > is cast to double *before* the absolute value is taken, as in the
    > attached patch.
    
    Nice catch, and the fix seems appropriate.
    
    			regards, tom lane