1 /*-------------------------------------------------------------------------
4 * Internal 64-bit integer operations
6 *-------------------------------------------------------------------------
19 #include "utils/int8.h"
24 #define INT_MAX (0x7FFFFFFFL)
27 #define INT_MIN (-INT_MAX-1)
30 #define SHRT_MAX (0x7FFF)
33 #define SHRT_MIN (-SHRT_MAX-1)
37 /***********************************************************************
39 ** Routines for 64-bit integers.
41 ***********************************************************************/
43 /*----------------------------------------------------------
44 * Formatting and conversion routines.
45 *---------------------------------------------------------*/
52 int64 *result = palloc(sizeof(int64));
57 if (!PointerIsValid(str))
58 elog(ERROR, "Bad (null) int8 external representation");
61 * Do our own scan, rather than relying on sscanf which might be
62 * broken for long long. NOTE: this will not detect int64 overflow...
63 * but sscanf doesn't either...
65 while (*ptr && isspace(*ptr)) /* skip leading spaces */
67 if (*ptr == '-') /* handle sign */
71 if (!isdigit(*ptr)) /* require at least one digit */
72 elog(ERROR, "Bad int8 external representation '%s'", str);
73 while (*ptr && isdigit(*ptr)) /* process digits */
74 tmp = tmp * 10 + (*ptr++ - '0');
75 if (*ptr) /* trailing junk? */
76 elog(ERROR, "Bad int8 external representation '%s'", str);
78 *result = (sign < 0) ? -tmp : tmp;
92 char buf[MAXINT8LEN + 1];
94 if (!PointerIsValid(val))
97 if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, *val)) < 0)
98 elog(ERROR, "Unable to format int8");
100 result = palloc(len + 1);
108 /*----------------------------------------------------------
109 * Relational operators for int8s.
110 *---------------------------------------------------------*/
113 * Is val1 relop val2?
116 int8eq(int64 *val1, int64 *val2)
121 return *val1 == *val2;
125 int8ne(int64 *val1, int64 *val2)
130 return *val1 != *val2;
134 int8lt(int64 *val1, int64 *val2)
139 return *val1 < *val2;
143 int8gt(int64 *val1, int64 *val2)
148 return *val1 > *val2;
152 int8le(int64 *val1, int64 *val2)
157 return *val1 <= *val2;
161 int8ge(int64 *val1, int64 *val2)
166 return *val1 >= *val2;
171 * Is 64-bit val1 relop 32-bit val2?
174 int84eq(int64 *val1, int32 val2)
179 return *val1 == val2;
183 int84ne(int64 *val1, int32 val2)
188 return *val1 != val2;
192 int84lt(int64 *val1, int32 val2)
201 int84gt(int64 *val1, int32 val2)
210 int84le(int64 *val1, int32 val2)
215 return *val1 <= val2;
219 int84ge(int64 *val1, int32 val2)
224 return *val1 >= val2;
229 * Is 32-bit val1 relop 64-bit val2?
232 int48eq(int32 val1, int64 *val2)
237 return val1 == *val2;
241 int48ne(int32 val1, int64 *val2)
246 return val1 != *val2;
250 int48lt(int32 val1, int64 *val2)
259 int48gt(int32 val1, int64 *val2)
268 int48le(int32 val1, int64 *val2)
273 return val1 <= *val2;
277 int48ge(int32 val1, int64 *val2)
282 return val1 >= *val2;
286 /*----------------------------------------------------------
287 * Arithmetic operators on 64-bit integers.
288 *---------------------------------------------------------*/
294 int64 *result = palloc(sizeof(int64));
296 if (!PointerIsValid(val))
299 result = int8mi(&temp, val);
306 int8pl(int64 *val1, int64 *val2)
308 int64 *result = palloc(sizeof(int64));
310 if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
313 *result = *val1 + *val2;
319 int8mi(int64 *val1, int64 *val2)
321 int64 *result = palloc(sizeof(int64));
323 if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
326 *result = *val1 - *val2;
332 int8mul(int64 *val1, int64 *val2)
334 int64 *result = palloc(sizeof(int64));
336 if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
339 *result = *val1 * *val2;
345 int8div(int64 *val1, int64 *val2)
347 int64 *result = palloc(sizeof(int64));
349 if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
352 *result = *val1 / *val2;
358 int8larger(int64 *val1, int64 *val2)
360 int64 *result = palloc(sizeof(int64));
362 if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
365 *result = ((*val1 > *val2) ? *val1 : *val2);
371 int8smaller(int64 *val1, int64 *val2)
373 int64 *result = palloc(sizeof(int64));
375 if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
378 *result = ((*val1 < *val2) ? *val1 : *val2);
381 } /* int8smaller() */
385 int84pl(int64 *val1, int32 val2)
387 int64 *result = palloc(sizeof(int64));
389 if (!PointerIsValid(val1))
392 *result = *val1 + (int64) val2;
398 int84mi(int64 *val1, int32 val2)
400 int64 *result = palloc(sizeof(int64));
402 if (!PointerIsValid(val1))
405 *result = *val1 - (int64) val2;
411 int84mul(int64 *val1, int32 val2)
413 int64 *result = palloc(sizeof(int64));
415 if (!PointerIsValid(val1))
418 *result = *val1 * (int64) val2;
424 int84div(int64 *val1, int32 val2)
426 int64 *result = palloc(sizeof(int64));
428 if (!PointerIsValid(val1))
431 *result = *val1 / (int64) val2;
438 int48pl(int32 val1, int64 *val2)
440 int64 *result = palloc(sizeof(int64));
442 if (!PointerIsValid(val2))
445 *result = (int64) val1 + *val2;
451 int48mi(int32 val1, int64 *val2)
453 int64 *result = palloc(sizeof(int64));
455 if (!PointerIsValid(val2))
458 *result = (int64) val1 - *val2;
464 int48mul(int32 val1, int64 *val2)
466 int64 *result = palloc(sizeof(int64));
468 if (!PointerIsValid(val2))
471 *result = (int64) val1 **val2;
477 int48div(int32 val1, int64 *val2)
479 int64 *result = palloc(sizeof(int64));
481 if (!PointerIsValid(val2))
484 *result = (int64) val1 / *val2;
490 /*----------------------------------------------------------
491 * Conversion operators.
492 *---------------------------------------------------------*/
497 int64 *result = palloc(sizeof(int64));
509 if (!PointerIsValid(val))
510 elog(ERROR, "Invalid (null) int64, can't convert int8 to int4");
512 if ((*val < INT_MIN) || (*val > INT_MAX))
513 elog(ERROR, "int8 conversion to int4 is out of range");
522 int2vector (int16 val)
526 result = palloc(sizeof(int64));
538 if (!PointerIsValid(val))
539 elog(ERROR, "Invalid (null) int8, can't convert to int2");
541 if ((*val < SHRT_MIN) || (*val > SHRT_MAX))
542 elog(ERROR, "int8 conversion to int2 is out of range");
554 float64 result = palloc(sizeof(float64data));
556 if (!PointerIsValid(val))
557 elog(ERROR, "Invalid (null) int8, can't convert to float8");
565 * Convert double float to 8-byte integer.
566 * Do a range check before the conversion.
567 * Note that the comparison probably isn't quite right
568 * since we only have ~52 bits of precision in a double float
569 * and so subtracting one from a large number gives the large
570 * number exactly. However, for some reason the comparison below
571 * does the right thing on my i686/linux-rh4.2 box.
572 * - thomas 1998-06-16
577 int64 *result = palloc(sizeof(int64));
579 if (!PointerIsValid(val))
580 elog(ERROR, "Invalid (null) float8, can't convert to int8");
582 if ((*val < (-pow(2, 63) + 1)) || (*val > (pow(2, 63) - 1)))
583 elog(ERROR, "Floating point conversion to int64 is out of range");
598 if (!PointerIsValid(str))
599 elog(ERROR, "Bad (null) int8 external representation");
601 len = (VARSIZE(str) - VARHDRSZ);
603 memmove(s, VARDATA(str), len);
613 int8_text(int64 *val)
620 if (!PointerIsValid(val))
626 result = palloc(VARHDRSZ + len);
628 VARSIZE(result) = len + VARHDRSZ;
629 memmove(VARDATA(result), s, len);