1/*-------------------------------------------------------------------------
4 * utility functions for I/O of built-in numeric types.
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/utils/adt/numutils.c
13 *-------------------------------------------------------------------------
26 * A table of all two-digit numbers. This is used to speed up decimal digit
27 * generation by copying pairs of digits into the final output.
30"00" "01" "02" "03" "04" "05" "06" "07" "08" "09"
31"10" "11" "12" "13" "14" "15" "16" "17" "18" "19"
32"20" "21" "22" "23" "24" "25" "26" "27" "28" "29"
33"30" "31" "32" "33" "34" "35" "36" "37" "38" "39"
34"40" "41" "42" "43" "44" "45" "46" "47" "48" "49"
35"50" "51" "52" "53" "54" "55" "56" "57" "58" "59"
36"60" "61" "62" "63" "64" "65" "66" "67" "68" "69"
37"70" "71" "72" "73" "74" "75" "76" "77" "78" "79"
38"80" "81" "82" "83" "84" "85" "86" "87" "88" "89"
39"90" "91" "92" "93" "94" "95" "96" "97" "98" "99";
42 * Adapted from http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
48 static const uint32 PowersOfTen[] = {
51 1000000, 10000000, 100000000,
56 * Compute base-10 logarithm by dividing the base-2 logarithm by a
57 * good-enough approximation of the base-2 logarithm of 10
60 return t + (v >= PowersOfTen[t]);
67 static const uint64 PowersOfTen[] = {
81 * Compute base-10 logarithm by dividing the base-2 logarithm by a
82 * good-enough approximation of the base-2 logarithm of 10
85 return t + (v >= PowersOfTen[t]);
89 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
90 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
91 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
92 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
93 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
94 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
95 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
96 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
100 * Convert input string to a signed 16 bit integer. Input strings may be
101 * expressed in base-10, hexadecimal, octal, or binary format, all of which
102 * can be prefixed by an optional sign character, either '+' (the default) or
103 * '-' for negative numbers. Hex strings are recognized by the digits being
104 * prefixed by 0x or 0X while octal strings are recognized by the 0o or 0O
105 * prefix. The binary representation is recognized by the 0b or 0B prefix.
107 * Allows any number of leading or trailing whitespace characters. Digits may
108 * optionally be separated by a single underscore character. These can only
109 * come between digits and not before or after the digits. Underscores have
110 * no effect on the return value and are supported only to assist in improving
111 * the human readability of the input strings.
113 * pg_strtoint16() will throw ereport() upon bad input format or overflow;
114 * while pg_strtoint16_safe() instead returns such complaints in *escontext,
115 * if it's an ErrorSaveContext.
117 * NB: Accumulate input as an unsigned number, to deal with two's complement
118 * representation of the most negative number, which can't be represented as a
119 * signed positive number.
131 const char *firstdigit;
138 * The majority of cases are likely to be base-10 digits without any
139 * underscore separator characters. We'll first try to parse the string
140 * with the assumption that's the case and only fallback on a slower
141 * implementation which handles hex, octal and binary strings and
142 * underscores if the fastpath version cannot parse the string.
145 /* leave it up to the slow path to look for leading spaces */
153 /* a leading '+' is uncommon so leave that for the slow path */
155 /* process the first digit */
156 digit = (*ptr -
'0');
159 * Exploit unsigned arithmetic to save having to check both the upper and
160 * lower bounds of the digit.
169 /* we need at least one digit */
173 /* process remaining digits */
176 digit = (*ptr -
'0');
186 tmp = tmp * 10 + digit;
189 /* when the string does not end in a digit, let the slow path handle it */
208 /* no need to reset neg */
210 /* skip leading spaces */
211 while (isspace((
unsigned char) *ptr))
220 else if (*ptr ==
'+')
224 if (ptr[0] ==
'0' && (ptr[1] ==
'x' || ptr[1] ==
'X'))
226 firstdigit = ptr += 2;
230 if (isxdigit((
unsigned char) *ptr))
235 tmp = tmp * 16 +
hexlookup[(
unsigned char) *ptr++];
237 else if (*ptr ==
'_')
239 /* underscore must be followed by more digits */
241 if (*ptr ==
'0円' || !isxdigit((
unsigned char) *ptr))
248 else if (ptr[0] ==
'0' && (ptr[1] ==
'o' || ptr[1] ==
'O'))
250 firstdigit = ptr += 2;
254 if (*ptr >=
'0' && *ptr <=
'7')
259 tmp = tmp * 8 + (*ptr++ -
'0');
261 else if (*ptr ==
'_')
263 /* underscore must be followed by more digits */
265 if (*ptr ==
'0円' || *ptr < '0' || *ptr >
'7')
272 else if (ptr[0] ==
'0' && (ptr[1] ==
'b' || ptr[1] ==
'B'))
274 firstdigit = ptr += 2;
278 if (*ptr >=
'0' && *ptr <=
'1')
283 tmp = tmp * 2 + (*ptr++ -
'0');
285 else if (*ptr ==
'_')
287 /* underscore must be followed by more digits */
289 if (*ptr ==
'0円' || *ptr < '0' || *ptr >
'1')
302 if (*ptr >=
'0' && *ptr <=
'9')
307 tmp = tmp * 10 + (*ptr++ -
'0');
309 else if (*ptr ==
'_')
311 /* underscore may not be first */
314 /* and it must be followed by more digits */
316 if (*ptr ==
'0円' || !isdigit((
unsigned char) *ptr))
324 /* require at least one digit */
328 /* allow trailing whitespace, but not other trailing chars */
329 while (isspace((
unsigned char) *ptr))
349 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
350 errmsg(
"value \"%s\" is out of range for type %s",
355 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
356 errmsg(
"invalid input syntax for type %s: \"%s\"",
361 * Convert input string to a signed 32 bit integer. Input strings may be
362 * expressed in base-10, hexadecimal, octal, or binary format, all of which
363 * can be prefixed by an optional sign character, either '+' (the default) or
364 * '-' for negative numbers. Hex strings are recognized by the digits being
365 * prefixed by 0x or 0X while octal strings are recognized by the 0o or 0O
366 * prefix. The binary representation is recognized by the 0b or 0B prefix.
368 * Allows any number of leading or trailing whitespace characters. Digits may
369 * optionally be separated by a single underscore character. These can only
370 * come between digits and not before or after the digits. Underscores have
371 * no effect on the return value and are supported only to assist in improving
372 * the human readability of the input strings.
374 * pg_strtoint32() will throw ereport() upon bad input format or overflow;
375 * while pg_strtoint32_safe() instead returns such complaints in *escontext,
376 * if it's an ErrorSaveContext.
378 * NB: Accumulate input as an unsigned number, to deal with two's complement
379 * representation of the most negative number, which can't be represented as a
380 * signed positive number.
392 const char *firstdigit;
399 * The majority of cases are likely to be base-10 digits without any
400 * underscore separator characters. We'll first try to parse the string
401 * with the assumption that's the case and only fallback on a slower
402 * implementation which handles hex, octal and binary strings and
403 * underscores if the fastpath version cannot parse the string.
406 /* leave it up to the slow path to look for leading spaces */
414 /* a leading '+' is uncommon so leave that for the slow path */
416 /* process the first digit */
417 digit = (*ptr -
'0');
420 * Exploit unsigned arithmetic to save having to check both the upper and
421 * lower bounds of the digit.
430 /* we need at least one digit */
434 /* process remaining digits */
437 digit = (*ptr -
'0');
447 tmp = tmp * 10 + digit;
450 /* when the string does not end in a digit, let the slow path handle it */
469 /* no need to reset neg */
471 /* skip leading spaces */
472 while (isspace((
unsigned char) *ptr))
481 else if (*ptr ==
'+')
485 if (ptr[0] ==
'0' && (ptr[1] ==
'x' || ptr[1] ==
'X'))
487 firstdigit = ptr += 2;
491 if (isxdigit((
unsigned char) *ptr))
496 tmp = tmp * 16 +
hexlookup[(
unsigned char) *ptr++];
498 else if (*ptr ==
'_')
500 /* underscore must be followed by more digits */
502 if (*ptr ==
'0円' || !isxdigit((
unsigned char) *ptr))
509 else if (ptr[0] ==
'0' && (ptr[1] ==
'o' || ptr[1] ==
'O'))
511 firstdigit = ptr += 2;
515 if (*ptr >=
'0' && *ptr <=
'7')
520 tmp = tmp * 8 + (*ptr++ -
'0');
522 else if (*ptr ==
'_')
524 /* underscore must be followed by more digits */
526 if (*ptr ==
'0円' || *ptr < '0' || *ptr >
'7')
533 else if (ptr[0] ==
'0' && (ptr[1] ==
'b' || ptr[1] ==
'B'))
535 firstdigit = ptr += 2;
539 if (*ptr >=
'0' && *ptr <=
'1')
544 tmp = tmp * 2 + (*ptr++ -
'0');
546 else if (*ptr ==
'_')
548 /* underscore must be followed by more digits */
550 if (*ptr ==
'0円' || *ptr < '0' || *ptr >
'1')
563 if (*ptr >=
'0' && *ptr <=
'9')
568 tmp = tmp * 10 + (*ptr++ -
'0');
570 else if (*ptr ==
'_')
572 /* underscore may not be first */
575 /* and it must be followed by more digits */
577 if (*ptr ==
'0円' || !isdigit((
unsigned char) *ptr))
585 /* require at least one digit */
589 /* allow trailing whitespace, but not other trailing chars */
590 while (isspace((
unsigned char) *ptr))
610 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
611 errmsg(
"value \"%s\" is out of range for type %s",
616 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
617 errmsg(
"invalid input syntax for type %s: \"%s\"",
622 * Convert input string to a signed 64 bit integer. Input strings may be
623 * expressed in base-10, hexadecimal, octal, or binary format, all of which
624 * can be prefixed by an optional sign character, either '+' (the default) or
625 * '-' for negative numbers. Hex strings are recognized by the digits being
626 * prefixed by 0x or 0X while octal strings are recognized by the 0o or 0O
627 * prefix. The binary representation is recognized by the 0b or 0B prefix.
629 * Allows any number of leading or trailing whitespace characters. Digits may
630 * optionally be separated by a single underscore character. These can only
631 * come between digits and not before or after the digits. Underscores have
632 * no effect on the return value and are supported only to assist in improving
633 * the human readability of the input strings.
635 * pg_strtoint64() will throw ereport() upon bad input format or overflow;
636 * while pg_strtoint64_safe() instead returns such complaints in *escontext,
637 * if it's an ErrorSaveContext.
639 * NB: Accumulate input as an unsigned number, to deal with two's complement
640 * representation of the most negative number, which can't be represented as a
641 * signed positive number.
653 const char *firstdigit;
660 * The majority of cases are likely to be base-10 digits without any
661 * underscore separator characters. We'll first try to parse the string
662 * with the assumption that's the case and only fallback on a slower
663 * implementation which handles hex, octal and binary strings and
664 * underscores if the fastpath version cannot parse the string.
667 /* leave it up to the slow path to look for leading spaces */
675 /* a leading '+' is uncommon so leave that for the slow path */
677 /* process the first digit */
678 digit = (*ptr -
'0');
681 * Exploit unsigned arithmetic to save having to check both the upper and
682 * lower bounds of the digit.
691 /* we need at least one digit */
695 /* process remaining digits */
698 digit = (*ptr -
'0');
708 tmp = tmp * 10 + digit;
711 /* when the string does not end in a digit, let the slow path handle it */
730 /* no need to reset neg */
732 /* skip leading spaces */
733 while (isspace((
unsigned char) *ptr))
742 else if (*ptr ==
'+')
746 if (ptr[0] ==
'0' && (ptr[1] ==
'x' || ptr[1] ==
'X'))
748 firstdigit = ptr += 2;
752 if (isxdigit((
unsigned char) *ptr))
757 tmp = tmp * 16 +
hexlookup[(
unsigned char) *ptr++];
759 else if (*ptr ==
'_')
761 /* underscore must be followed by more digits */
763 if (*ptr ==
'0円' || !isxdigit((
unsigned char) *ptr))
770 else if (ptr[0] ==
'0' && (ptr[1] ==
'o' || ptr[1] ==
'O'))
772 firstdigit = ptr += 2;
776 if (*ptr >=
'0' && *ptr <=
'7')
781 tmp = tmp * 8 + (*ptr++ -
'0');
783 else if (*ptr ==
'_')
785 /* underscore must be followed by more digits */
787 if (*ptr ==
'0円' || *ptr < '0' || *ptr >
'7')
794 else if (ptr[0] ==
'0' && (ptr[1] ==
'b' || ptr[1] ==
'B'))
796 firstdigit = ptr += 2;
800 if (*ptr >=
'0' && *ptr <=
'1')
805 tmp = tmp * 2 + (*ptr++ -
'0');
807 else if (*ptr ==
'_')
809 /* underscore must be followed by more digits */
811 if (*ptr ==
'0円' || *ptr < '0' || *ptr >
'1')
824 if (*ptr >=
'0' && *ptr <=
'9')
829 tmp = tmp * 10 + (*ptr++ -
'0');
831 else if (*ptr ==
'_')
833 /* underscore may not be first */
836 /* and it must be followed by more digits */
838 if (*ptr ==
'0円' || !isdigit((
unsigned char) *ptr))
846 /* require at least one digit */
850 /* allow trailing whitespace, but not other trailing chars */
851 while (isspace((
unsigned char) *ptr))
871 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
872 errmsg(
"value \"%s\" is out of range for type %s",
877 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
878 errmsg(
"invalid input syntax for type %s: \"%s\"",
883 * Convert input string to an unsigned 32 bit integer.
885 * Allows any number of leading or trailing whitespace characters.
887 * If endloc isn't NULL, store a pointer to the rest of the string there,
888 * so that caller can parse the rest. Otherwise, it's an error if anything
889 * but whitespace follows.
891 * typname is what is reported in error messages.
893 * If escontext points to an ErrorSaveContext node, that is filled instead
894 * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
906 cvt = strtoul(s, &endptr, 0);
909 * strtoul() normally only sets ERANGE. On some systems it may also set
910 * EINVAL, which simply means it couldn't parse the input string. Be sure
911 * to report that the same way as the standard error indication (that
914 if ((errno && errno != ERANGE) || endptr == s)
916 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
917 errmsg(
"invalid input syntax for type %s: \"%s\"",
922 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
923 errmsg(
"value \"%s\" is out of range for type %s",
928 /* caller wants to deal with rest of string */
933 /* allow only whitespace after number */
934 while (*endptr && isspace((
unsigned char) *endptr))
938 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
939 errmsg(
"invalid input syntax for type %s: \"%s\"",
946 * Cope with possibility that unsigned long is wider than uint32, in which
947 * case strtoul will not raise an error for some values that are out of
948 * the range of uint32.
950 * For backwards compatibility, we want to accept inputs that are given
951 * with a minus sign, so allow the input value if it matches after either
952 * signed or unsigned extension to long.
954 * To ensure consistent results on 32-bit and 64-bit platforms, make sure
955 * the error message is the same as if strtoul() had returned ERANGE.
957#if PG_UINT32_MAX != ULONG_MAX
958 if (cvt != (
unsigned long) result &&
959 cvt != (
unsigned long) ((
int) result))
961 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
962 errmsg(
"value \"%s\" is out of range for type %s",
970 * Convert input string to an unsigned 64 bit integer.
972 * Allows any number of leading or trailing whitespace characters.
974 * If endloc isn't NULL, store a pointer to the rest of the string there,
975 * so that caller can parse the rest. Otherwise, it's an error if anything
976 * but whitespace follows.
978 * typname is what is reported in error messages.
980 * If escontext points to an ErrorSaveContext node, that is filled instead
981 * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
992 result = strtou64(s, &endptr, 0);
995 * strtoul[l] normally only sets ERANGE. On some systems it may also set
996 * EINVAL, which simply means it couldn't parse the input string. Be sure
997 * to report that the same way as the standard error indication (that
1000 if ((errno && errno != ERANGE) || endptr == s)
1002 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1003 errmsg(
"invalid input syntax for type %s: \"%s\"",
1006 if (errno == ERANGE)
1008 (
errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1009 errmsg(
"value \"%s\" is out of range for type %s",
1014 /* caller wants to deal with rest of string */
1019 /* allow only whitespace after number */
1020 while (*endptr && isspace((
unsigned char) *endptr))
1024 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1025 errmsg(
"invalid input syntax for type %s: \"%s\"",
1033 * pg_itoa: converts a signed 16-bit integer to its string representation
1034 * and returns strlen(a).
1036 * Caller must ensure that 'a' points to enough memory to hold the result
1037 * (at least 7 bytes, counting a leading sign and trailing NUL).
1039 * It doesn't seem worth implementing this separately.
1048 * pg_ultoa_n: converts an unsigned 32-bit integer to its string representation,
1049 * not NUL-terminated, and returns the length of that string representation
1051 * Caller must ensure that 'a' points to enough memory to hold the result (at
1060 /* Degenerate case */
1069 /* Compute the result string. */
1070 while (
value >= 10000)
1073 const uint32 c0 = (
c % 100) << 1;
1074 const uint32 c1 = (
c / 100) << 1;
1076 char *pos =
a + olength -
i;
1088 char *pos =
a + olength -
i;
1099 char *pos =
a + olength -
i;
1105 *
a = (char) (
'0' +
value);
1112 * pg_ltoa: converts a signed 32-bit integer to its string representation and
1113 * returns strlen(a).
1115 * It is the caller's responsibility to ensure that a is at least 12 bytes long,
1116 * which is enough room to hold a minus sign, a maximally long int32, and the
1117 * above terminating NUL.
1127 uvalue = (
uint32) 0 - uvalue;
1136 * Get the decimal representation, not NUL-terminated, and return the length of
1137 * same. Caller must ensure that a points to at least MAXINT8LEN bytes.
1146 /* Degenerate case */
1155 /* Compute the result string. */
1156 while (
value >= 100000000)
1161 const uint32 c = value3 % 10000;
1162 const uint32 d = value3 / 10000;
1163 const uint32 c0 = (
c % 100) << 1;
1164 const uint32 c1 = (
c / 100) << 1;
1165 const uint32 d0 = (d % 100) << 1;
1166 const uint32 d1 = (d / 100) << 1;
1168 char *pos =
a + olength -
i;
1179 /* Switch to 32-bit for speed */
1182 if (value2 >= 10000)
1184 const uint32 c = value2 - 10000 * (value2 / 10000);
1185 const uint32 c0 = (
c % 100) << 1;
1186 const uint32 c1 = (
c / 100) << 1;
1188 char *pos =
a + olength -
i;
1198 const uint32 c = (value2 % 100) << 1;
1199 char *pos =
a + olength -
i;
1209 char *pos =
a + olength -
i;
1214 *
a = (char) (
'0' + value2);
1220 * pg_lltoa: converts a signed 64-bit integer to its string representation and
1221 * returns strlen(a).
1223 * Caller must ensure that 'a' points to enough memory to hold the result
1224 * (at least MAXINT8LEN + 1 bytes, counting a leading sign and trailing NUL).
1234 uvalue = (
uint64) 0 - uvalue;
1245 * pg_ultostr_zeropad
1246 * Converts 'value' into a decimal string representation stored at 'str'.
1247 * 'minwidth' specifies the minimum width of the result; any extra space
1248 * is filled up by prefixing the number with zeros.
1250 * Returns the ending address of the string result (the last character written
1251 * plus 1). Note that no NUL terminator is written.
1253 * The intended use-case for this function is to build strings that contain
1254 * multiple individual numbers, for example:
1256 * str = pg_ultostr_zeropad(str, hours, 2);
1258 * str = pg_ultostr_zeropad(str, mins, 2);
1260 * str = pg_ultostr_zeropad(str, secs, 2);
1263 * Note: Caller must ensure that 'str' points to enough memory to hold the
1273 if (
value < 100 && minwidth == 2)
/* Short cut for common case */
1280 if (
len >= minwidth)
1284 memset(
str,
'0', minwidth -
len);
1285 return str + minwidth;
1290 * Converts 'value' into a decimal string representation stored at 'str'.
1292 * Returns the ending address of the string result (the last character written
1293 * plus 1). Note that no NUL terminator is written.
1295 * The intended use-case for this function is to build strings that contain
1296 * multiple individual numbers, for example:
1298 * str = pg_ultostr(str, a);
1300 * str = pg_ultostr(str, b);
1303 * Note: Caller must ensure that 'str' points to enough memory to hold the
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereturn(context, dummy_value,...)
Assert(PointerIsAligned(start, uint64))
static bool pg_neg_u32_overflow(uint32 a, int32 *result)
static bool pg_neg_u16_overflow(uint16 a, int16 *result)
static bool pg_neg_u64_overflow(uint64 a, int64 *result)
int64 pg_strtoint64_safe(const char *s, Node *escontext)
uint64 uint64in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
int64 pg_strtoint64(const char *s)
int pg_ltoa(int32 value, char *a)
char * pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth)
int32 pg_strtoint32_safe(const char *s, Node *escontext)
int pg_ulltoa_n(uint64 value, char *a)
int16 pg_strtoint16(const char *s)
static const char DIGIT_TABLE[200]
static int decimalLength32(const uint32 v)
uint32 uint32in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
int pg_lltoa(int64 value, char *a)
char * pg_ultostr(char *str, uint32 value)
static int decimalLength64(const uint64 v)
int pg_itoa(int16 i, char *a)
int32 pg_strtoint32(const char *s)
int16 pg_strtoint16_safe(const char *s, Node *escontext)
static const int8 hexlookup[128]
int pg_ultoa_n(uint32 value, char *a)
static int pg_leftmost_one_pos32(uint32 word)
static int pg_leftmost_one_pos64(uint64 word)