From: | Andrew Gierth <andrew(at)tao11(dot)riddles(dot)org(dot)uk> |
---|---|
To: | David Fetter <david(at)fetter(dot)org> |
Cc: | Kyotaro Horiguchi <horikyota(dot)ntt(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: Efficient output for integer types |
Date: | 2019-09-23 12:16:36 |
Message-ID: | 87pnjrns08.fsf@news-spur.riddles.org.uk |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
>>>>> "David" == David Fetter <david(at)fetter(dot)org> writes:
David> + return pg_ltostr_zeropad(str, (uint32)0 - (uint32)value, minwidth - 1);
No, this is just reintroducing the undefined behavior again. Once the
value has been converted to unsigned you can't cast it back to signed or
pass it to a function expecting a signed value, since it will overflow
in the INT_MIN case. (and in this example would probably output '-'
signs until it ran off the end of memory).
Here's how I would do it:
char *
pg_ltostr_zeropad(char *str, int32 value, int32 minwidth)
{
int32 len;
uint32 uvalue = value;
Assert(minwidth > 0);
if (value >= 0)
{
if (value < 100 && minwidth == 2) /* Short cut for common case */
{
memcpy(str, DIGIT_TABLE + value*2, 2);
return str + 2;
}
}
else
{
*str++ = '-';
minwidth -= 1;
uvalue = (uint32)0 - uvalue;
}
len = pg_ultoa_n(uvalue, str);
if (len >= minwidth)
return str + len;
memmove(str + minwidth - len, str, len);
memset(str, '0', minwidth - len);
return str + minwidth;
}
David> pg_ltostr(char *str, int32 value)
David> + int32 len = pg_ultoa_n(value, str);
David> + return str + len;
This seems to have lost its handling of negative numbers entirely (which
doesn't say much for the regression test coverage)
--
Andrew (irc:RhodiumToad)
From | Date | Subject | |
---|---|---|---|
Next Message | Robert Haas | 2019-09-23 12:58:00 | Re: Unwanted expression simplification in PG12b2 |
Previous Message | Tomas Vondra | 2019-09-23 11:45:14 | Re: PATCH: standby crashed when replay block which truncated in standby but failed to truncate in master node |