1 /*-------------------------------------------------------------------------
4 * Internal 64-bit integer operations
6 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.36 2001/11/24 19:57:06 tgl Exp $
12 *-------------------------------------------------------------------------
22 #include "utils/int8.h"
24 /* this should be set in pg_config.h, but just in case it wasn't: */
26 #define INT64_FORMAT "%ld"
29 #ifdef HAVE_LL_CONSTANTS
30 #define INT64CONST(x) ((int64) x##LL)
32 #define INT64CONST(x) ((int64) x)
38 #define INT_MAX (0x7FFFFFFFL)
41 #define INT_MIN (-INT_MAX-1)
44 #define SHRT_MAX (0x7FFF)
47 #define SHRT_MIN (-SHRT_MAX-1)
51 /***********************************************************************
53 ** Routines for 64-bit integers.
55 ***********************************************************************/
57 /*----------------------------------------------------------
58 * Formatting and conversion routines.
59 *---------------------------------------------------------*/
64 int8in(PG_FUNCTION_ARGS)
66 char *str = PG_GETARG_CSTRING(0);
73 * Do our own scan, rather than relying on sscanf which might be
74 * broken for long long.
76 while (*ptr && isspace((unsigned char) *ptr)) /* skip leading spaces */
84 * Do an explicit check for INT64_MIN. Ugly though this is, it's
85 * cleaner than trying to get the loop below to handle it portably.
87 #ifndef INT64_IS_BUSTED
88 if (strcmp(ptr, "9223372036854775808") == 0)
90 result = - INT64CONST(0x7fffffffffffffff) - 1;
91 PG_RETURN_INT64(result);
97 if (!isdigit((unsigned char) *ptr)) /* require at least one digit */
98 elog(ERROR, "Bad int8 external representation \"%s\"", str);
99 while (*ptr && isdigit((unsigned char) *ptr)) /* process digits */
101 int64 newtmp = tmp * 10 + (*ptr++ - '0');
103 if ((newtmp / 10) != tmp) /* overflow? */
104 elog(ERROR, "int8 value out of range: \"%s\"", str);
107 if (*ptr) /* trailing junk? */
108 elog(ERROR, "Bad int8 external representation \"%s\"", str);
110 result = (sign < 0) ? -tmp : tmp;
112 PG_RETURN_INT64(result);
119 int8out(PG_FUNCTION_ARGS)
121 int64 val = PG_GETARG_INT64(0);
124 char buf[MAXINT8LEN + 1];
126 if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, val)) < 0)
127 elog(ERROR, "Unable to format int8");
129 result = pstrdup(buf);
130 PG_RETURN_CSTRING(result);
134 /*----------------------------------------------------------
135 * Relational operators for int8s, including cross-data-type comparisons.
136 *---------------------------------------------------------*/
139 * Is val1 relop val2?
142 int8eq(PG_FUNCTION_ARGS)
144 int64 val1 = PG_GETARG_INT64(0);
145 int64 val2 = PG_GETARG_INT64(1);
147 PG_RETURN_BOOL(val1 == val2);
151 int8ne(PG_FUNCTION_ARGS)
153 int64 val1 = PG_GETARG_INT64(0);
154 int64 val2 = PG_GETARG_INT64(1);
156 PG_RETURN_BOOL(val1 != val2);
160 int8lt(PG_FUNCTION_ARGS)
162 int64 val1 = PG_GETARG_INT64(0);
163 int64 val2 = PG_GETARG_INT64(1);
165 PG_RETURN_BOOL(val1 < val2);
169 int8gt(PG_FUNCTION_ARGS)
171 int64 val1 = PG_GETARG_INT64(0);
172 int64 val2 = PG_GETARG_INT64(1);
174 PG_RETURN_BOOL(val1 > val2);
178 int8le(PG_FUNCTION_ARGS)
180 int64 val1 = PG_GETARG_INT64(0);
181 int64 val2 = PG_GETARG_INT64(1);
183 PG_RETURN_BOOL(val1 <= val2);
187 int8ge(PG_FUNCTION_ARGS)
189 int64 val1 = PG_GETARG_INT64(0);
190 int64 val2 = PG_GETARG_INT64(1);
192 PG_RETURN_BOOL(val1 >= val2);
196 * Is 64-bit val1 relop 32-bit val2?
199 int84eq(PG_FUNCTION_ARGS)
201 int64 val1 = PG_GETARG_INT64(0);
202 int32 val2 = PG_GETARG_INT32(1);
204 PG_RETURN_BOOL(val1 == val2);
208 int84ne(PG_FUNCTION_ARGS)
210 int64 val1 = PG_GETARG_INT64(0);
211 int32 val2 = PG_GETARG_INT32(1);
213 PG_RETURN_BOOL(val1 != val2);
217 int84lt(PG_FUNCTION_ARGS)
219 int64 val1 = PG_GETARG_INT64(0);
220 int32 val2 = PG_GETARG_INT32(1);
222 PG_RETURN_BOOL(val1 < val2);
226 int84gt(PG_FUNCTION_ARGS)
228 int64 val1 = PG_GETARG_INT64(0);
229 int32 val2 = PG_GETARG_INT32(1);
231 PG_RETURN_BOOL(val1 > val2);
235 int84le(PG_FUNCTION_ARGS)
237 int64 val1 = PG_GETARG_INT64(0);
238 int32 val2 = PG_GETARG_INT32(1);
240 PG_RETURN_BOOL(val1 <= val2);
244 int84ge(PG_FUNCTION_ARGS)
246 int64 val1 = PG_GETARG_INT64(0);
247 int32 val2 = PG_GETARG_INT32(1);
249 PG_RETURN_BOOL(val1 >= val2);
253 * Is 32-bit val1 relop 64-bit val2?
256 int48eq(PG_FUNCTION_ARGS)
258 int32 val1 = PG_GETARG_INT32(0);
259 int64 val2 = PG_GETARG_INT64(1);
261 PG_RETURN_BOOL(val1 == val2);
265 int48ne(PG_FUNCTION_ARGS)
267 int32 val1 = PG_GETARG_INT32(0);
268 int64 val2 = PG_GETARG_INT64(1);
270 PG_RETURN_BOOL(val1 != val2);
274 int48lt(PG_FUNCTION_ARGS)
276 int32 val1 = PG_GETARG_INT32(0);
277 int64 val2 = PG_GETARG_INT64(1);
279 PG_RETURN_BOOL(val1 < val2);
283 int48gt(PG_FUNCTION_ARGS)
285 int32 val1 = PG_GETARG_INT32(0);
286 int64 val2 = PG_GETARG_INT64(1);
288 PG_RETURN_BOOL(val1 > val2);
292 int48le(PG_FUNCTION_ARGS)
294 int32 val1 = PG_GETARG_INT32(0);
295 int64 val2 = PG_GETARG_INT64(1);
297 PG_RETURN_BOOL(val1 <= val2);
301 int48ge(PG_FUNCTION_ARGS)
303 int32 val1 = PG_GETARG_INT32(0);
304 int64 val2 = PG_GETARG_INT64(1);
306 PG_RETURN_BOOL(val1 >= val2);
310 * Is 64-bit val1 relop 16-bit val2?
313 int82eq(PG_FUNCTION_ARGS)
315 int64 val1 = PG_GETARG_INT64(0);
316 int16 val2 = PG_GETARG_INT16(1);
318 PG_RETURN_BOOL(val1 == val2);
322 int82ne(PG_FUNCTION_ARGS)
324 int64 val1 = PG_GETARG_INT64(0);
325 int16 val2 = PG_GETARG_INT16(1);
327 PG_RETURN_BOOL(val1 != val2);
331 int82lt(PG_FUNCTION_ARGS)
333 int64 val1 = PG_GETARG_INT64(0);
334 int16 val2 = PG_GETARG_INT16(1);
336 PG_RETURN_BOOL(val1 < val2);
340 int82gt(PG_FUNCTION_ARGS)
342 int64 val1 = PG_GETARG_INT64(0);
343 int16 val2 = PG_GETARG_INT16(1);
345 PG_RETURN_BOOL(val1 > val2);
349 int82le(PG_FUNCTION_ARGS)
351 int64 val1 = PG_GETARG_INT64(0);
352 int16 val2 = PG_GETARG_INT16(1);
354 PG_RETURN_BOOL(val1 <= val2);
358 int82ge(PG_FUNCTION_ARGS)
360 int64 val1 = PG_GETARG_INT64(0);
361 int16 val2 = PG_GETARG_INT16(1);
363 PG_RETURN_BOOL(val1 >= val2);
367 * Is 16-bit val1 relop 64-bit val2?
370 int28eq(PG_FUNCTION_ARGS)
372 int16 val1 = PG_GETARG_INT16(0);
373 int64 val2 = PG_GETARG_INT64(1);
375 PG_RETURN_BOOL(val1 == val2);
379 int28ne(PG_FUNCTION_ARGS)
381 int16 val1 = PG_GETARG_INT16(0);
382 int64 val2 = PG_GETARG_INT64(1);
384 PG_RETURN_BOOL(val1 != val2);
388 int28lt(PG_FUNCTION_ARGS)
390 int16 val1 = PG_GETARG_INT16(0);
391 int64 val2 = PG_GETARG_INT64(1);
393 PG_RETURN_BOOL(val1 < val2);
397 int28gt(PG_FUNCTION_ARGS)
399 int16 val1 = PG_GETARG_INT16(0);
400 int64 val2 = PG_GETARG_INT64(1);
402 PG_RETURN_BOOL(val1 > val2);
406 int28le(PG_FUNCTION_ARGS)
408 int16 val1 = PG_GETARG_INT16(0);
409 int64 val2 = PG_GETARG_INT64(1);
411 PG_RETURN_BOOL(val1 <= val2);
415 int28ge(PG_FUNCTION_ARGS)
417 int16 val1 = PG_GETARG_INT16(0);
418 int64 val2 = PG_GETARG_INT64(1);
420 PG_RETURN_BOOL(val1 >= val2);
424 /*----------------------------------------------------------
425 * Arithmetic operators on 64-bit integers.
426 *---------------------------------------------------------*/
429 int8um(PG_FUNCTION_ARGS)
431 int64 val = PG_GETARG_INT64(0);
433 PG_RETURN_INT64(-val);
437 int8up(PG_FUNCTION_ARGS)
439 int64 val = PG_GETARG_INT64(0);
441 PG_RETURN_INT64(val);
445 int8pl(PG_FUNCTION_ARGS)
447 int64 val1 = PG_GETARG_INT64(0);
448 int64 val2 = PG_GETARG_INT64(1);
450 PG_RETURN_INT64(val1 + val2);
454 int8mi(PG_FUNCTION_ARGS)
456 int64 val1 = PG_GETARG_INT64(0);
457 int64 val2 = PG_GETARG_INT64(1);
459 PG_RETURN_INT64(val1 - val2);
463 int8mul(PG_FUNCTION_ARGS)
465 int64 val1 = PG_GETARG_INT64(0);
466 int64 val2 = PG_GETARG_INT64(1);
468 PG_RETURN_INT64(val1 * val2);
472 int8div(PG_FUNCTION_ARGS)
474 int64 val1 = PG_GETARG_INT64(0);
475 int64 val2 = PG_GETARG_INT64(1);
477 PG_RETURN_INT64(val1 / val2);
484 int8abs(PG_FUNCTION_ARGS)
486 int64 arg1 = PG_GETARG_INT64(0);
488 PG_RETURN_INT64((arg1 < 0) ? -arg1 : arg1);
495 int8mod(PG_FUNCTION_ARGS)
497 int64 val1 = PG_GETARG_INT64(0);
498 int64 val2 = PG_GETARG_INT64(1);
501 result = val1 / val2;
503 result = val1 - result;
505 PG_RETURN_INT64(result);
512 int8fac(PG_FUNCTION_ARGS)
514 int64 arg1 = PG_GETARG_INT64(0);
521 for (i = arg1, result = 1; i > 0; --i)
524 PG_RETURN_INT64(result);
528 int8inc(PG_FUNCTION_ARGS)
530 int64 arg = PG_GETARG_INT64(0);
532 PG_RETURN_INT64(arg + 1);
536 int8larger(PG_FUNCTION_ARGS)
538 int64 val1 = PG_GETARG_INT64(0);
539 int64 val2 = PG_GETARG_INT64(1);
542 result = ((val1 > val2) ? val1 : val2);
544 PG_RETURN_INT64(result);
548 int8smaller(PG_FUNCTION_ARGS)
550 int64 val1 = PG_GETARG_INT64(0);
551 int64 val2 = PG_GETARG_INT64(1);
554 result = ((val1 < val2) ? val1 : val2);
556 PG_RETURN_INT64(result);
560 int84pl(PG_FUNCTION_ARGS)
562 int64 val1 = PG_GETARG_INT64(0);
563 int32 val2 = PG_GETARG_INT32(1);
565 PG_RETURN_INT64(val1 + val2);
569 int84mi(PG_FUNCTION_ARGS)
571 int64 val1 = PG_GETARG_INT64(0);
572 int32 val2 = PG_GETARG_INT32(1);
574 PG_RETURN_INT64(val1 - val2);
578 int84mul(PG_FUNCTION_ARGS)
580 int64 val1 = PG_GETARG_INT64(0);
581 int32 val2 = PG_GETARG_INT32(1);
583 PG_RETURN_INT64(val1 * val2);
587 int84div(PG_FUNCTION_ARGS)
589 int64 val1 = PG_GETARG_INT64(0);
590 int32 val2 = PG_GETARG_INT32(1);
592 PG_RETURN_INT64(val1 / val2);
596 int48pl(PG_FUNCTION_ARGS)
598 int32 val1 = PG_GETARG_INT32(0);
599 int64 val2 = PG_GETARG_INT64(1);
601 PG_RETURN_INT64(val1 + val2);
605 int48mi(PG_FUNCTION_ARGS)
607 int32 val1 = PG_GETARG_INT32(0);
608 int64 val2 = PG_GETARG_INT64(1);
610 PG_RETURN_INT64(val1 - val2);
614 int48mul(PG_FUNCTION_ARGS)
616 int32 val1 = PG_GETARG_INT32(0);
617 int64 val2 = PG_GETARG_INT64(1);
619 PG_RETURN_INT64(val1 * val2);
623 int48div(PG_FUNCTION_ARGS)
625 int32 val1 = PG_GETARG_INT32(0);
626 int64 val2 = PG_GETARG_INT64(1);
628 PG_RETURN_INT64(val1 / val2);
631 /* Binary arithmetics
633 * int8and - returns arg1 & arg2
634 * int8or - returns arg1 | arg2
635 * int8xor - returns arg1 # arg2
636 * int8not - returns ~arg1
637 * int8shl - returns arg1 << arg2
638 * int8shr - returns arg1 >> arg2
642 int8and(PG_FUNCTION_ARGS)
644 int64 arg1 = PG_GETARG_INT64(0);
645 int64 arg2 = PG_GETARG_INT64(1);
647 PG_RETURN_INT64(arg1 & arg2);
651 int8or(PG_FUNCTION_ARGS)
653 int64 arg1 = PG_GETARG_INT64(0);
654 int64 arg2 = PG_GETARG_INT64(1);
656 PG_RETURN_INT64(arg1 | arg2);
660 int8xor(PG_FUNCTION_ARGS)
662 int64 arg1 = PG_GETARG_INT64(0);
663 int64 arg2 = PG_GETARG_INT64(1);
665 PG_RETURN_INT64(arg1 ^ arg2);
669 int8not(PG_FUNCTION_ARGS)
671 int64 arg1 = PG_GETARG_INT64(0);
673 PG_RETURN_INT64(~arg1);
677 int8shl(PG_FUNCTION_ARGS)
679 int64 arg1 = PG_GETARG_INT64(0);
680 int32 arg2 = PG_GETARG_INT32(1);
682 PG_RETURN_INT64(arg1 << arg2);
686 int8shr(PG_FUNCTION_ARGS)
688 int64 arg1 = PG_GETARG_INT64(0);
689 int32 arg2 = PG_GETARG_INT32(1);
691 PG_RETURN_INT64(arg1 >> arg2);
694 /*----------------------------------------------------------
695 * Conversion operators.
696 *---------------------------------------------------------*/
699 int48(PG_FUNCTION_ARGS)
701 int32 val = PG_GETARG_INT32(0);
703 PG_RETURN_INT64((int64) val);
707 int84(PG_FUNCTION_ARGS)
709 int64 val = PG_GETARG_INT64(0);
712 result = (int32) val;
714 /* Test for overflow by reverse-conversion. */
715 if ((int64) result != val)
716 elog(ERROR, "int8 conversion to int4 is out of range");
718 PG_RETURN_INT32(result);
722 int28(PG_FUNCTION_ARGS)
724 int16 val = PG_GETARG_INT16(0);
726 PG_RETURN_INT64((int64) val);
730 int82(PG_FUNCTION_ARGS)
732 int64 val = PG_GETARG_INT64(0);
735 result = (int16) val;
737 /* Test for overflow by reverse-conversion. */
738 if ((int64) result != val)
739 elog(ERROR, "int8 conversion to int2 is out of range");
741 PG_RETURN_INT16(result);
745 i8tod(PG_FUNCTION_ARGS)
747 int64 val = PG_GETARG_INT64(0);
752 PG_RETURN_FLOAT8(result);
756 * Convert double float to 8-byte integer.
759 dtoi8(PG_FUNCTION_ARGS)
761 float8 val = PG_GETARG_FLOAT8(0);
764 /* Round val to nearest integer (but it's still in float form) */
768 * Does it fit in an int64? Avoid assuming that we have handy
769 * constants defined for the range boundaries, instead test for
770 * overflow by reverse-conversion.
772 result = (int64) val;
774 if ((float8) result != val)
775 elog(ERROR, "Floating point conversion to int8 is out of range");
777 PG_RETURN_INT64(result);
783 text_int8(PG_FUNCTION_ARGS)
785 text *str = PG_GETARG_TEXT_P(0);
790 len = (VARSIZE(str) - VARHDRSZ);
792 memcpy(s, VARDATA(str), len);
795 result = DirectFunctionCall1(int8in, CStringGetDatum(s));
806 int8_text(PG_FUNCTION_ARGS)
808 /* val is int64, but easier to leave it as Datum */
809 Datum val = PG_GETARG_DATUM(0);
814 s = DatumGetCString(DirectFunctionCall1(int8out, val));
817 result = (text *) palloc(VARHDRSZ + len);
819 VARATT_SIZEP(result) = len + VARHDRSZ;
820 memcpy(VARDATA(result), s, len);
824 PG_RETURN_TEXT_P(result);