Re: Remove dependence on integer wrapping

From: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
To: Nathan Bossart <nathandbossart(at)gmail(dot)com>
Cc: jian he <jian(dot)universality(at)gmail(dot)com>, Joseph Koshakow <koshy44(at)gmail(dot)com>, Matthew Kim <matthewkmkim(at)gmail(dot)com>, Alexander Lakhin <exclusion(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Andres Freund <andres(at)anarazel(dot)de>
Subject: Re: Remove dependence on integer wrapping
Date: 2024-08-14 19:29:39
Message-ID: d33f2c31-1fcf-44be-8a39-686c524a389c@iki.fi
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 14/08/2024 20:20, Nathan Bossart wrote:
> On Wed, Aug 14, 2024 at 10:02:28AM +0300, Heikki Linnakangas wrote:
>> On 14/08/2024 06:07, Nathan Bossart wrote:
>>> * - If a * b overflows, return true, otherwise store the result of a * b
>>> * into *result. The content of *result is implementation defined in case of
>>> * overflow.
>>> + * - If -a overflows, return true, otherwise store the result of -a into
>>> + * *result. The content of *result is implementation defined in case of
>>> + * overflow.
>>> + * - Return the absolute value of a as an unsigned integer of the same
>>> + * width.
>>> *---------
>>> */
>>
>> The last "Return the absolute value of a ..." sentence feels a bit weird. In
>> all the preceding sentences, 'a' is part of an "If a" sentence that defines
>> what 'a' is. In the last one, it's kind of just hanging there.
>
> How about:
>
> If a is negative, return -a, otherwise return a. Overflow cannot occur
> because the return value is an unsigned integer with the same width as
> the argument.

Hmm, that still doesn't say what operation it's referring to. They
existing comments say "a + b", "a - b" or "a * b", but this one isn't
referring to anything at all. IMHO the existing comments are not too
clear on that either though. How about something like this:

/*---------
*
* The following guidelines apply to all the *_overflow routines:
*
* If the result overflows, return true, otherwise store the result into
* *result. The content of *result is implementation defined in case of
* overflow
*
* bool pg_add_*_overflow(a, b, *result)
*
* Calculate a + b
*
* bool pg_sub_*_overflow(a, b, *result)
*
* Calculate a - b
*
* bool pg_mul_*_overflow(a, b, *result)
*
* Calculate a * b
*
* bool pg_neg_*_overflow(a, *result)
*
* Calculate -a
*
*
* In addition, this file contains:
*
* <unsigned int type> pg_abs_*(<signed int type> a)
*
* Calculate absolute value of a. Unlike the standard library abs() and
* labs() functions, the the return type is unsigned, and the operation
* cannot overflow.
*---------
*/

>>> +static inline uint16
>>> +pg_abs_s16(int16 a)
>>> +{
>>> + return abs(a);
>>> +}
>>> +
>>
>> This is correct, but it took me a while to understand why. Maybe some
>> comments would be in order.
>>
>> The function it calls is "int abs(int)". So this first widens the int16 to
>> int32, and then narrows the result from int32 to uint16.
>>
>> The man page for abs() says "Trying to take the absolute value of the most
>> negative integer is not defined." That's OK in this case, because that
>> refers to the most negative int32 value, and the argument here is int16. But
>> that's why the pg_abs_s64(int64) function needs the special check for the
>> most negative value.
>
> Yeah, I've added some casts/comments to make this clear. I got too excited
> about trimming it down and ended up obfuscating these important details.

That's better, thanks!

--
Heikki Linnakangas
Neon (https://neon.tech)

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Nathan Bossart 2024-08-14 19:38:59 Re: Remove dependence on integer wrapping
Previous Message Robert Haas 2024-08-14 19:23:05 Re: generic plans and "initial" pruning