From: | Gaetano Mendola <mendola(at)bigfoot(dot)com> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Subject: | Re: Checking for overflow of integer arithmetic |
Date: | 2004-10-04 00:11:46 |
Message-ID: | 41609542.7090805@bigfoot.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Tom Lane wrote:
> {
> int32 arg1 = PG_GETARG_INT32(0);
> int32 arg2 = PG_GETARG_INT32(1);
> + int32 result;
>
> ! result = arg1 * arg2;
> ! /*
> ! * Overflow check. We basically check to see if result / arg2 gives
> ! * arg1 again. There are two cases where this fails: arg2 = 0 (which
> ! * cannot overflow) and arg1 = INT_MIN, arg2 = -1 (where the division
> ! * itself will overflow and thus incorrectly match).
> ! *
> ! * Since the division is likely much more expensive than the actual
> ! * multiplication, we'd like to skip it where possible. The best
> ! * bang for the buck seems to be to check whether both inputs are in
> ! * the int16 range; if so, no overflow is possible.
> ! */
> ! if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
> ! arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
> ! arg2 != 0 &&
> ! (result/arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
> ! ereport(ERROR,
> ! (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
> ! errmsg("integer out of range")));
> ! PG_RETURN_INT32(result);
> }
May be is a good idea postpone the division as second "OR" argument in order to hope to avoid
it.
Regards
Gaetano Mendola
From | Date | Subject | |
---|---|---|---|
Next Message | Zeugswetter Andreas SB SD | 2004-10-04 07:21:00 | Re: AIX and V8 beta 3 |
Previous Message | Bruno Wolff III | 2004-10-03 23:29:42 | Re: Checking for overflow of integer arithmetic |