1 /*-------------------------------------------------------------------------
4 * Internal 64-bit integer operations
6 * Portions Copyright (c) 1996-2002, 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.41 2002/09/04 20:31:28 momjian Exp $
12 *-------------------------------------------------------------------------
22 #include "utils/int8.h"
28 #define INT_MAX (0x7FFFFFFFL)
31 #define INT_MIN (-INT_MAX-1)
34 #define SHRT_MAX (0x7FFF)
37 #define SHRT_MIN (-SHRT_MAX-1)
41 /***********************************************************************
43 ** Routines for 64-bit integers.
45 ***********************************************************************/
47 /*----------------------------------------------------------
48 * Formatting and conversion routines.
49 *---------------------------------------------------------*/
54 int8in(PG_FUNCTION_ARGS)
56 char *str = PG_GETARG_CSTRING(0);
63 * Do our own scan, rather than relying on sscanf which might be
64 * broken for long long.
66 while (*ptr && isspace((unsigned char) *ptr)) /* skip leading spaces */
75 * Do an explicit check for INT64_MIN. Ugly though this is, it's
76 * cleaner than trying to get the loop below to handle it
79 #ifndef INT64_IS_BUSTED
80 if (strcmp(ptr, "9223372036854775808") == 0)
82 result = -INT64CONST(0x7fffffffffffffff) - 1;
83 PG_RETURN_INT64(result);
89 if (!isdigit((unsigned char) *ptr)) /* require at least one digit */
90 elog(ERROR, "Bad int8 external representation \"%s\"", str);
91 while (*ptr && isdigit((unsigned char) *ptr)) /* process digits */
93 int64 newtmp = tmp * 10 + (*ptr++ - '0');
95 if ((newtmp / 10) != tmp) /* overflow? */
96 elog(ERROR, "int8 value out of range: \"%s\"", str);
99 if (*ptr) /* trailing junk? */
100 elog(ERROR, "Bad int8 external representation \"%s\"", str);
102 result = (sign < 0) ? -tmp : tmp;
104 PG_RETURN_INT64(result);
111 int8out(PG_FUNCTION_ARGS)
113 int64 val = PG_GETARG_INT64(0);
116 char buf[MAXINT8LEN + 1];
118 if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, val)) < 0)
119 elog(ERROR, "Unable to format int8");
121 result = pstrdup(buf);
122 PG_RETURN_CSTRING(result);
126 /*----------------------------------------------------------
127 * Relational operators for int8s, including cross-data-type comparisons.
128 *---------------------------------------------------------*/
131 * Is val1 relop val2?
134 int8eq(PG_FUNCTION_ARGS)
136 int64 val1 = PG_GETARG_INT64(0);
137 int64 val2 = PG_GETARG_INT64(1);
139 PG_RETURN_BOOL(val1 == val2);
143 int8ne(PG_FUNCTION_ARGS)
145 int64 val1 = PG_GETARG_INT64(0);
146 int64 val2 = PG_GETARG_INT64(1);
148 PG_RETURN_BOOL(val1 != val2);
152 int8lt(PG_FUNCTION_ARGS)
154 int64 val1 = PG_GETARG_INT64(0);
155 int64 val2 = PG_GETARG_INT64(1);
157 PG_RETURN_BOOL(val1 < val2);
161 int8gt(PG_FUNCTION_ARGS)
163 int64 val1 = PG_GETARG_INT64(0);
164 int64 val2 = PG_GETARG_INT64(1);
166 PG_RETURN_BOOL(val1 > val2);
170 int8le(PG_FUNCTION_ARGS)
172 int64 val1 = PG_GETARG_INT64(0);
173 int64 val2 = PG_GETARG_INT64(1);
175 PG_RETURN_BOOL(val1 <= val2);
179 int8ge(PG_FUNCTION_ARGS)
181 int64 val1 = PG_GETARG_INT64(0);
182 int64 val2 = PG_GETARG_INT64(1);
184 PG_RETURN_BOOL(val1 >= val2);
188 * Is 64-bit val1 relop 32-bit val2?
191 int84eq(PG_FUNCTION_ARGS)
193 int64 val1 = PG_GETARG_INT64(0);
194 int32 val2 = PG_GETARG_INT32(1);
196 PG_RETURN_BOOL(val1 == val2);
200 int84ne(PG_FUNCTION_ARGS)
202 int64 val1 = PG_GETARG_INT64(0);
203 int32 val2 = PG_GETARG_INT32(1);
205 PG_RETURN_BOOL(val1 != val2);
209 int84lt(PG_FUNCTION_ARGS)
211 int64 val1 = PG_GETARG_INT64(0);
212 int32 val2 = PG_GETARG_INT32(1);
214 PG_RETURN_BOOL(val1 < val2);
218 int84gt(PG_FUNCTION_ARGS)
220 int64 val1 = PG_GETARG_INT64(0);
221 int32 val2 = PG_GETARG_INT32(1);
223 PG_RETURN_BOOL(val1 > val2);
227 int84le(PG_FUNCTION_ARGS)
229 int64 val1 = PG_GETARG_INT64(0);
230 int32 val2 = PG_GETARG_INT32(1);
232 PG_RETURN_BOOL(val1 <= val2);
236 int84ge(PG_FUNCTION_ARGS)
238 int64 val1 = PG_GETARG_INT64(0);
239 int32 val2 = PG_GETARG_INT32(1);
241 PG_RETURN_BOOL(val1 >= val2);
245 * Is 32-bit val1 relop 64-bit val2?
248 int48eq(PG_FUNCTION_ARGS)
250 int32 val1 = PG_GETARG_INT32(0);
251 int64 val2 = PG_GETARG_INT64(1);
253 PG_RETURN_BOOL(val1 == val2);
257 int48ne(PG_FUNCTION_ARGS)
259 int32 val1 = PG_GETARG_INT32(0);
260 int64 val2 = PG_GETARG_INT64(1);
262 PG_RETURN_BOOL(val1 != val2);
266 int48lt(PG_FUNCTION_ARGS)
268 int32 val1 = PG_GETARG_INT32(0);
269 int64 val2 = PG_GETARG_INT64(1);
271 PG_RETURN_BOOL(val1 < val2);
275 int48gt(PG_FUNCTION_ARGS)
277 int32 val1 = PG_GETARG_INT32(0);
278 int64 val2 = PG_GETARG_INT64(1);
280 PG_RETURN_BOOL(val1 > val2);
284 int48le(PG_FUNCTION_ARGS)
286 int32 val1 = PG_GETARG_INT32(0);
287 int64 val2 = PG_GETARG_INT64(1);
289 PG_RETURN_BOOL(val1 <= val2);
293 int48ge(PG_FUNCTION_ARGS)
295 int32 val1 = PG_GETARG_INT32(0);
296 int64 val2 = PG_GETARG_INT64(1);
298 PG_RETURN_BOOL(val1 >= val2);
302 * Is 64-bit val1 relop 16-bit val2?
305 int82eq(PG_FUNCTION_ARGS)
307 int64 val1 = PG_GETARG_INT64(0);
308 int16 val2 = PG_GETARG_INT16(1);
310 PG_RETURN_BOOL(val1 == val2);
314 int82ne(PG_FUNCTION_ARGS)
316 int64 val1 = PG_GETARG_INT64(0);
317 int16 val2 = PG_GETARG_INT16(1);
319 PG_RETURN_BOOL(val1 != val2);
323 int82lt(PG_FUNCTION_ARGS)
325 int64 val1 = PG_GETARG_INT64(0);
326 int16 val2 = PG_GETARG_INT16(1);
328 PG_RETURN_BOOL(val1 < val2);
332 int82gt(PG_FUNCTION_ARGS)
334 int64 val1 = PG_GETARG_INT64(0);
335 int16 val2 = PG_GETARG_INT16(1);
337 PG_RETURN_BOOL(val1 > val2);
341 int82le(PG_FUNCTION_ARGS)
343 int64 val1 = PG_GETARG_INT64(0);
344 int16 val2 = PG_GETARG_INT16(1);
346 PG_RETURN_BOOL(val1 <= val2);
350 int82ge(PG_FUNCTION_ARGS)
352 int64 val1 = PG_GETARG_INT64(0);
353 int16 val2 = PG_GETARG_INT16(1);
355 PG_RETURN_BOOL(val1 >= val2);
359 * Is 16-bit val1 relop 64-bit val2?
362 int28eq(PG_FUNCTION_ARGS)
364 int16 val1 = PG_GETARG_INT16(0);
365 int64 val2 = PG_GETARG_INT64(1);
367 PG_RETURN_BOOL(val1 == val2);
371 int28ne(PG_FUNCTION_ARGS)
373 int16 val1 = PG_GETARG_INT16(0);
374 int64 val2 = PG_GETARG_INT64(1);
376 PG_RETURN_BOOL(val1 != val2);
380 int28lt(PG_FUNCTION_ARGS)
382 int16 val1 = PG_GETARG_INT16(0);
383 int64 val2 = PG_GETARG_INT64(1);
385 PG_RETURN_BOOL(val1 < val2);
389 int28gt(PG_FUNCTION_ARGS)
391 int16 val1 = PG_GETARG_INT16(0);
392 int64 val2 = PG_GETARG_INT64(1);
394 PG_RETURN_BOOL(val1 > val2);
398 int28le(PG_FUNCTION_ARGS)
400 int16 val1 = PG_GETARG_INT16(0);
401 int64 val2 = PG_GETARG_INT64(1);
403 PG_RETURN_BOOL(val1 <= val2);
407 int28ge(PG_FUNCTION_ARGS)
409 int16 val1 = PG_GETARG_INT16(0);
410 int64 val2 = PG_GETARG_INT64(1);
412 PG_RETURN_BOOL(val1 >= val2);
416 /*----------------------------------------------------------
417 * Arithmetic operators on 64-bit integers.
418 *---------------------------------------------------------*/
421 int8um(PG_FUNCTION_ARGS)
423 int64 val = PG_GETARG_INT64(0);
425 PG_RETURN_INT64(-val);
429 int8up(PG_FUNCTION_ARGS)
431 int64 val = PG_GETARG_INT64(0);
433 PG_RETURN_INT64(val);
437 int8pl(PG_FUNCTION_ARGS)
439 int64 val1 = PG_GETARG_INT64(0);
440 int64 val2 = PG_GETARG_INT64(1);
442 PG_RETURN_INT64(val1 + val2);
446 int8mi(PG_FUNCTION_ARGS)
448 int64 val1 = PG_GETARG_INT64(0);
449 int64 val2 = PG_GETARG_INT64(1);
451 PG_RETURN_INT64(val1 - val2);
455 int8mul(PG_FUNCTION_ARGS)
457 int64 val1 = PG_GETARG_INT64(0);
458 int64 val2 = PG_GETARG_INT64(1);
460 PG_RETURN_INT64(val1 * val2);
464 int8div(PG_FUNCTION_ARGS)
466 int64 val1 = PG_GETARG_INT64(0);
467 int64 val2 = PG_GETARG_INT64(1);
469 PG_RETURN_INT64(val1 / val2);
476 int8abs(PG_FUNCTION_ARGS)
478 int64 arg1 = PG_GETARG_INT64(0);
480 PG_RETURN_INT64((arg1 < 0) ? -arg1 : arg1);
487 int8mod(PG_FUNCTION_ARGS)
489 int64 val1 = PG_GETARG_INT64(0);
490 int64 val2 = PG_GETARG_INT64(1);
493 result = val1 / val2;
495 result = val1 - result;
497 PG_RETURN_INT64(result);
504 int8fac(PG_FUNCTION_ARGS)
506 int64 arg1 = PG_GETARG_INT64(0);
515 for (i = arg1, result = 1; i > 0; --i)
518 PG_RETURN_INT64(result);
522 int8inc(PG_FUNCTION_ARGS)
524 int64 arg = PG_GETARG_INT64(0);
526 PG_RETURN_INT64(arg + 1);
530 int8larger(PG_FUNCTION_ARGS)
532 int64 val1 = PG_GETARG_INT64(0);
533 int64 val2 = PG_GETARG_INT64(1);
536 result = ((val1 > val2) ? val1 : val2);
538 PG_RETURN_INT64(result);
542 int8smaller(PG_FUNCTION_ARGS)
544 int64 val1 = PG_GETARG_INT64(0);
545 int64 val2 = PG_GETARG_INT64(1);
548 result = ((val1 < val2) ? val1 : val2);
550 PG_RETURN_INT64(result);
554 int84pl(PG_FUNCTION_ARGS)
556 int64 val1 = PG_GETARG_INT64(0);
557 int32 val2 = PG_GETARG_INT32(1);
559 PG_RETURN_INT64(val1 + val2);
563 int84mi(PG_FUNCTION_ARGS)
565 int64 val1 = PG_GETARG_INT64(0);
566 int32 val2 = PG_GETARG_INT32(1);
568 PG_RETURN_INT64(val1 - val2);
572 int84mul(PG_FUNCTION_ARGS)
574 int64 val1 = PG_GETARG_INT64(0);
575 int32 val2 = PG_GETARG_INT32(1);
577 PG_RETURN_INT64(val1 * val2);
581 int84div(PG_FUNCTION_ARGS)
583 int64 val1 = PG_GETARG_INT64(0);
584 int32 val2 = PG_GETARG_INT32(1);
586 PG_RETURN_INT64(val1 / val2);
590 int48pl(PG_FUNCTION_ARGS)
592 int32 val1 = PG_GETARG_INT32(0);
593 int64 val2 = PG_GETARG_INT64(1);
595 PG_RETURN_INT64(val1 + val2);
599 int48mi(PG_FUNCTION_ARGS)
601 int32 val1 = PG_GETARG_INT32(0);
602 int64 val2 = PG_GETARG_INT64(1);
604 PG_RETURN_INT64(val1 - val2);
608 int48mul(PG_FUNCTION_ARGS)
610 int32 val1 = PG_GETARG_INT32(0);
611 int64 val2 = PG_GETARG_INT64(1);
613 PG_RETURN_INT64(val1 * val2);
617 int48div(PG_FUNCTION_ARGS)
619 int32 val1 = PG_GETARG_INT32(0);
620 int64 val2 = PG_GETARG_INT64(1);
622 PG_RETURN_INT64(val1 / val2);
625 /* Binary arithmetics
627 * int8and - returns arg1 & arg2
628 * int8or - returns arg1 | arg2
629 * int8xor - returns arg1 # arg2
630 * int8not - returns ~arg1
631 * int8shl - returns arg1 << arg2
632 * int8shr - returns arg1 >> arg2
636 int8and(PG_FUNCTION_ARGS)
638 int64 arg1 = PG_GETARG_INT64(0);
639 int64 arg2 = PG_GETARG_INT64(1);
641 PG_RETURN_INT64(arg1 & arg2);
645 int8or(PG_FUNCTION_ARGS)
647 int64 arg1 = PG_GETARG_INT64(0);
648 int64 arg2 = PG_GETARG_INT64(1);
650 PG_RETURN_INT64(arg1 | arg2);
654 int8xor(PG_FUNCTION_ARGS)
656 int64 arg1 = PG_GETARG_INT64(0);
657 int64 arg2 = PG_GETARG_INT64(1);
659 PG_RETURN_INT64(arg1 ^ arg2);
663 int8not(PG_FUNCTION_ARGS)
665 int64 arg1 = PG_GETARG_INT64(0);
667 PG_RETURN_INT64(~arg1);
671 int8shl(PG_FUNCTION_ARGS)
673 int64 arg1 = PG_GETARG_INT64(0);
674 int32 arg2 = PG_GETARG_INT32(1);
676 PG_RETURN_INT64(arg1 << arg2);
680 int8shr(PG_FUNCTION_ARGS)
682 int64 arg1 = PG_GETARG_INT64(0);
683 int32 arg2 = PG_GETARG_INT32(1);
685 PG_RETURN_INT64(arg1 >> arg2);
688 /*----------------------------------------------------------
689 * Conversion operators.
690 *---------------------------------------------------------*/
693 int48(PG_FUNCTION_ARGS)
695 int32 val = PG_GETARG_INT32(0);
697 PG_RETURN_INT64((int64) val);
701 int84(PG_FUNCTION_ARGS)
703 int64 val = PG_GETARG_INT64(0);
706 result = (int32) val;
708 /* Test for overflow by reverse-conversion. */
709 if ((int64) result != val)
710 elog(ERROR, "int8 conversion to int4 is out of range");
712 PG_RETURN_INT32(result);
716 int28(PG_FUNCTION_ARGS)
718 int16 val = PG_GETARG_INT16(0);
720 PG_RETURN_INT64((int64) val);
724 int82(PG_FUNCTION_ARGS)
726 int64 val = PG_GETARG_INT64(0);
729 result = (int16) val;
731 /* Test for overflow by reverse-conversion. */
732 if ((int64) result != val)
733 elog(ERROR, "int8 conversion to int2 is out of range");
735 PG_RETURN_INT16(result);
739 i8tod(PG_FUNCTION_ARGS)
741 int64 val = PG_GETARG_INT64(0);
746 PG_RETURN_FLOAT8(result);
750 * Convert double float to 8-byte integer.
753 dtoi8(PG_FUNCTION_ARGS)
755 float8 val = PG_GETARG_FLOAT8(0);
758 /* Round val to nearest integer (but it's still in float form) */
762 * Does it fit in an int64? Avoid assuming that we have handy
763 * constants defined for the range boundaries, instead test for
764 * overflow by reverse-conversion.
766 result = (int64) val;
768 if ((float8) result != val)
769 elog(ERROR, "Floating point conversion to int8 is out of range");
771 PG_RETURN_INT64(result);
777 text_int8(PG_FUNCTION_ARGS)
779 text *str = PG_GETARG_TEXT_P(0);
784 len = (VARSIZE(str) - VARHDRSZ);
786 memcpy(s, VARDATA(str), len);
789 result = DirectFunctionCall1(int8in, CStringGetDatum(s));
800 int8_text(PG_FUNCTION_ARGS)
802 /* val is int64, but easier to leave it as Datum */
803 Datum val = PG_GETARG_DATUM(0);
808 s = DatumGetCString(DirectFunctionCall1(int8out, val));
811 result = (text *) palloc(VARHDRSZ + len);
813 VARATT_SIZEP(result) = len + VARHDRSZ;
814 memcpy(VARDATA(result), s, len);
818 PG_RETURN_TEXT_P(result);