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.40 2002/06/20 20:29:37 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 */
74 * Do an explicit check for INT64_MIN. Ugly though this is, it's
75 * cleaner than trying to get the loop below to handle it portably.
77 #ifndef INT64_IS_BUSTED
78 if (strcmp(ptr, "9223372036854775808") == 0)
80 result = - INT64CONST(0x7fffffffffffffff) - 1;
81 PG_RETURN_INT64(result);
87 if (!isdigit((unsigned char) *ptr)) /* require at least one digit */
88 elog(ERROR, "Bad int8 external representation \"%s\"", str);
89 while (*ptr && isdigit((unsigned char) *ptr)) /* process digits */
91 int64 newtmp = tmp * 10 + (*ptr++ - '0');
93 if ((newtmp / 10) != tmp) /* overflow? */
94 elog(ERROR, "int8 value out of range: \"%s\"", str);
97 if (*ptr) /* trailing junk? */
98 elog(ERROR, "Bad int8 external representation \"%s\"", str);
100 result = (sign < 0) ? -tmp : tmp;
102 PG_RETURN_INT64(result);
109 int8out(PG_FUNCTION_ARGS)
111 int64 val = PG_GETARG_INT64(0);
114 char buf[MAXINT8LEN + 1];
116 if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, val)) < 0)
117 elog(ERROR, "Unable to format int8");
119 result = pstrdup(buf);
120 PG_RETURN_CSTRING(result);
124 /*----------------------------------------------------------
125 * Relational operators for int8s, including cross-data-type comparisons.
126 *---------------------------------------------------------*/
129 * Is val1 relop val2?
132 int8eq(PG_FUNCTION_ARGS)
134 int64 val1 = PG_GETARG_INT64(0);
135 int64 val2 = PG_GETARG_INT64(1);
137 PG_RETURN_BOOL(val1 == val2);
141 int8ne(PG_FUNCTION_ARGS)
143 int64 val1 = PG_GETARG_INT64(0);
144 int64 val2 = PG_GETARG_INT64(1);
146 PG_RETURN_BOOL(val1 != val2);
150 int8lt(PG_FUNCTION_ARGS)
152 int64 val1 = PG_GETARG_INT64(0);
153 int64 val2 = PG_GETARG_INT64(1);
155 PG_RETURN_BOOL(val1 < val2);
159 int8gt(PG_FUNCTION_ARGS)
161 int64 val1 = PG_GETARG_INT64(0);
162 int64 val2 = PG_GETARG_INT64(1);
164 PG_RETURN_BOOL(val1 > val2);
168 int8le(PG_FUNCTION_ARGS)
170 int64 val1 = PG_GETARG_INT64(0);
171 int64 val2 = PG_GETARG_INT64(1);
173 PG_RETURN_BOOL(val1 <= val2);
177 int8ge(PG_FUNCTION_ARGS)
179 int64 val1 = PG_GETARG_INT64(0);
180 int64 val2 = PG_GETARG_INT64(1);
182 PG_RETURN_BOOL(val1 >= val2);
186 * Is 64-bit val1 relop 32-bit val2?
189 int84eq(PG_FUNCTION_ARGS)
191 int64 val1 = PG_GETARG_INT64(0);
192 int32 val2 = PG_GETARG_INT32(1);
194 PG_RETURN_BOOL(val1 == val2);
198 int84ne(PG_FUNCTION_ARGS)
200 int64 val1 = PG_GETARG_INT64(0);
201 int32 val2 = PG_GETARG_INT32(1);
203 PG_RETURN_BOOL(val1 != val2);
207 int84lt(PG_FUNCTION_ARGS)
209 int64 val1 = PG_GETARG_INT64(0);
210 int32 val2 = PG_GETARG_INT32(1);
212 PG_RETURN_BOOL(val1 < val2);
216 int84gt(PG_FUNCTION_ARGS)
218 int64 val1 = PG_GETARG_INT64(0);
219 int32 val2 = PG_GETARG_INT32(1);
221 PG_RETURN_BOOL(val1 > val2);
225 int84le(PG_FUNCTION_ARGS)
227 int64 val1 = PG_GETARG_INT64(0);
228 int32 val2 = PG_GETARG_INT32(1);
230 PG_RETURN_BOOL(val1 <= val2);
234 int84ge(PG_FUNCTION_ARGS)
236 int64 val1 = PG_GETARG_INT64(0);
237 int32 val2 = PG_GETARG_INT32(1);
239 PG_RETURN_BOOL(val1 >= val2);
243 * Is 32-bit val1 relop 64-bit val2?
246 int48eq(PG_FUNCTION_ARGS)
248 int32 val1 = PG_GETARG_INT32(0);
249 int64 val2 = PG_GETARG_INT64(1);
251 PG_RETURN_BOOL(val1 == val2);
255 int48ne(PG_FUNCTION_ARGS)
257 int32 val1 = PG_GETARG_INT32(0);
258 int64 val2 = PG_GETARG_INT64(1);
260 PG_RETURN_BOOL(val1 != val2);
264 int48lt(PG_FUNCTION_ARGS)
266 int32 val1 = PG_GETARG_INT32(0);
267 int64 val2 = PG_GETARG_INT64(1);
269 PG_RETURN_BOOL(val1 < val2);
273 int48gt(PG_FUNCTION_ARGS)
275 int32 val1 = PG_GETARG_INT32(0);
276 int64 val2 = PG_GETARG_INT64(1);
278 PG_RETURN_BOOL(val1 > val2);
282 int48le(PG_FUNCTION_ARGS)
284 int32 val1 = PG_GETARG_INT32(0);
285 int64 val2 = PG_GETARG_INT64(1);
287 PG_RETURN_BOOL(val1 <= val2);
291 int48ge(PG_FUNCTION_ARGS)
293 int32 val1 = PG_GETARG_INT32(0);
294 int64 val2 = PG_GETARG_INT64(1);
296 PG_RETURN_BOOL(val1 >= val2);
300 * Is 64-bit val1 relop 16-bit val2?
303 int82eq(PG_FUNCTION_ARGS)
305 int64 val1 = PG_GETARG_INT64(0);
306 int16 val2 = PG_GETARG_INT16(1);
308 PG_RETURN_BOOL(val1 == val2);
312 int82ne(PG_FUNCTION_ARGS)
314 int64 val1 = PG_GETARG_INT64(0);
315 int16 val2 = PG_GETARG_INT16(1);
317 PG_RETURN_BOOL(val1 != val2);
321 int82lt(PG_FUNCTION_ARGS)
323 int64 val1 = PG_GETARG_INT64(0);
324 int16 val2 = PG_GETARG_INT16(1);
326 PG_RETURN_BOOL(val1 < val2);
330 int82gt(PG_FUNCTION_ARGS)
332 int64 val1 = PG_GETARG_INT64(0);
333 int16 val2 = PG_GETARG_INT16(1);
335 PG_RETURN_BOOL(val1 > val2);
339 int82le(PG_FUNCTION_ARGS)
341 int64 val1 = PG_GETARG_INT64(0);
342 int16 val2 = PG_GETARG_INT16(1);
344 PG_RETURN_BOOL(val1 <= val2);
348 int82ge(PG_FUNCTION_ARGS)
350 int64 val1 = PG_GETARG_INT64(0);
351 int16 val2 = PG_GETARG_INT16(1);
353 PG_RETURN_BOOL(val1 >= val2);
357 * Is 16-bit val1 relop 64-bit val2?
360 int28eq(PG_FUNCTION_ARGS)
362 int16 val1 = PG_GETARG_INT16(0);
363 int64 val2 = PG_GETARG_INT64(1);
365 PG_RETURN_BOOL(val1 == val2);
369 int28ne(PG_FUNCTION_ARGS)
371 int16 val1 = PG_GETARG_INT16(0);
372 int64 val2 = PG_GETARG_INT64(1);
374 PG_RETURN_BOOL(val1 != val2);
378 int28lt(PG_FUNCTION_ARGS)
380 int16 val1 = PG_GETARG_INT16(0);
381 int64 val2 = PG_GETARG_INT64(1);
383 PG_RETURN_BOOL(val1 < val2);
387 int28gt(PG_FUNCTION_ARGS)
389 int16 val1 = PG_GETARG_INT16(0);
390 int64 val2 = PG_GETARG_INT64(1);
392 PG_RETURN_BOOL(val1 > val2);
396 int28le(PG_FUNCTION_ARGS)
398 int16 val1 = PG_GETARG_INT16(0);
399 int64 val2 = PG_GETARG_INT64(1);
401 PG_RETURN_BOOL(val1 <= val2);
405 int28ge(PG_FUNCTION_ARGS)
407 int16 val1 = PG_GETARG_INT16(0);
408 int64 val2 = PG_GETARG_INT64(1);
410 PG_RETURN_BOOL(val1 >= val2);
414 /*----------------------------------------------------------
415 * Arithmetic operators on 64-bit integers.
416 *---------------------------------------------------------*/
419 int8um(PG_FUNCTION_ARGS)
421 int64 val = PG_GETARG_INT64(0);
423 PG_RETURN_INT64(-val);
427 int8up(PG_FUNCTION_ARGS)
429 int64 val = PG_GETARG_INT64(0);
431 PG_RETURN_INT64(val);
435 int8pl(PG_FUNCTION_ARGS)
437 int64 val1 = PG_GETARG_INT64(0);
438 int64 val2 = PG_GETARG_INT64(1);
440 PG_RETURN_INT64(val1 + val2);
444 int8mi(PG_FUNCTION_ARGS)
446 int64 val1 = PG_GETARG_INT64(0);
447 int64 val2 = PG_GETARG_INT64(1);
449 PG_RETURN_INT64(val1 - val2);
453 int8mul(PG_FUNCTION_ARGS)
455 int64 val1 = PG_GETARG_INT64(0);
456 int64 val2 = PG_GETARG_INT64(1);
458 PG_RETURN_INT64(val1 * val2);
462 int8div(PG_FUNCTION_ARGS)
464 int64 val1 = PG_GETARG_INT64(0);
465 int64 val2 = PG_GETARG_INT64(1);
467 PG_RETURN_INT64(val1 / val2);
474 int8abs(PG_FUNCTION_ARGS)
476 int64 arg1 = PG_GETARG_INT64(0);
478 PG_RETURN_INT64((arg1 < 0) ? -arg1 : arg1);
485 int8mod(PG_FUNCTION_ARGS)
487 int64 val1 = PG_GETARG_INT64(0);
488 int64 val2 = PG_GETARG_INT64(1);
491 result = val1 / val2;
493 result = val1 - result;
495 PG_RETURN_INT64(result);
502 int8fac(PG_FUNCTION_ARGS)
504 int64 arg1 = PG_GETARG_INT64(0);
513 for (i = arg1, result = 1; i > 0; --i)
516 PG_RETURN_INT64(result);
520 int8inc(PG_FUNCTION_ARGS)
522 int64 arg = PG_GETARG_INT64(0);
524 PG_RETURN_INT64(arg + 1);
528 int8larger(PG_FUNCTION_ARGS)
530 int64 val1 = PG_GETARG_INT64(0);
531 int64 val2 = PG_GETARG_INT64(1);
534 result = ((val1 > val2) ? val1 : val2);
536 PG_RETURN_INT64(result);
540 int8smaller(PG_FUNCTION_ARGS)
542 int64 val1 = PG_GETARG_INT64(0);
543 int64 val2 = PG_GETARG_INT64(1);
546 result = ((val1 < val2) ? val1 : val2);
548 PG_RETURN_INT64(result);
552 int84pl(PG_FUNCTION_ARGS)
554 int64 val1 = PG_GETARG_INT64(0);
555 int32 val2 = PG_GETARG_INT32(1);
557 PG_RETURN_INT64(val1 + val2);
561 int84mi(PG_FUNCTION_ARGS)
563 int64 val1 = PG_GETARG_INT64(0);
564 int32 val2 = PG_GETARG_INT32(1);
566 PG_RETURN_INT64(val1 - val2);
570 int84mul(PG_FUNCTION_ARGS)
572 int64 val1 = PG_GETARG_INT64(0);
573 int32 val2 = PG_GETARG_INT32(1);
575 PG_RETURN_INT64(val1 * val2);
579 int84div(PG_FUNCTION_ARGS)
581 int64 val1 = PG_GETARG_INT64(0);
582 int32 val2 = PG_GETARG_INT32(1);
584 PG_RETURN_INT64(val1 / val2);
588 int48pl(PG_FUNCTION_ARGS)
590 int32 val1 = PG_GETARG_INT32(0);
591 int64 val2 = PG_GETARG_INT64(1);
593 PG_RETURN_INT64(val1 + val2);
597 int48mi(PG_FUNCTION_ARGS)
599 int32 val1 = PG_GETARG_INT32(0);
600 int64 val2 = PG_GETARG_INT64(1);
602 PG_RETURN_INT64(val1 - val2);
606 int48mul(PG_FUNCTION_ARGS)
608 int32 val1 = PG_GETARG_INT32(0);
609 int64 val2 = PG_GETARG_INT64(1);
611 PG_RETURN_INT64(val1 * val2);
615 int48div(PG_FUNCTION_ARGS)
617 int32 val1 = PG_GETARG_INT32(0);
618 int64 val2 = PG_GETARG_INT64(1);
620 PG_RETURN_INT64(val1 / val2);
623 /* Binary arithmetics
625 * int8and - returns arg1 & arg2
626 * int8or - returns arg1 | arg2
627 * int8xor - returns arg1 # arg2
628 * int8not - returns ~arg1
629 * int8shl - returns arg1 << arg2
630 * int8shr - returns arg1 >> arg2
634 int8and(PG_FUNCTION_ARGS)
636 int64 arg1 = PG_GETARG_INT64(0);
637 int64 arg2 = PG_GETARG_INT64(1);
639 PG_RETURN_INT64(arg1 & arg2);
643 int8or(PG_FUNCTION_ARGS)
645 int64 arg1 = PG_GETARG_INT64(0);
646 int64 arg2 = PG_GETARG_INT64(1);
648 PG_RETURN_INT64(arg1 | arg2);
652 int8xor(PG_FUNCTION_ARGS)
654 int64 arg1 = PG_GETARG_INT64(0);
655 int64 arg2 = PG_GETARG_INT64(1);
657 PG_RETURN_INT64(arg1 ^ arg2);
661 int8not(PG_FUNCTION_ARGS)
663 int64 arg1 = PG_GETARG_INT64(0);
665 PG_RETURN_INT64(~arg1);
669 int8shl(PG_FUNCTION_ARGS)
671 int64 arg1 = PG_GETARG_INT64(0);
672 int32 arg2 = PG_GETARG_INT32(1);
674 PG_RETURN_INT64(arg1 << arg2);
678 int8shr(PG_FUNCTION_ARGS)
680 int64 arg1 = PG_GETARG_INT64(0);
681 int32 arg2 = PG_GETARG_INT32(1);
683 PG_RETURN_INT64(arg1 >> arg2);
686 /*----------------------------------------------------------
687 * Conversion operators.
688 *---------------------------------------------------------*/
691 int48(PG_FUNCTION_ARGS)
693 int32 val = PG_GETARG_INT32(0);
695 PG_RETURN_INT64((int64) val);
699 int84(PG_FUNCTION_ARGS)
701 int64 val = PG_GETARG_INT64(0);
704 result = (int32) val;
706 /* Test for overflow by reverse-conversion. */
707 if ((int64) result != val)
708 elog(ERROR, "int8 conversion to int4 is out of range");
710 PG_RETURN_INT32(result);
714 int28(PG_FUNCTION_ARGS)
716 int16 val = PG_GETARG_INT16(0);
718 PG_RETURN_INT64((int64) val);
722 int82(PG_FUNCTION_ARGS)
724 int64 val = PG_GETARG_INT64(0);
727 result = (int16) val;
729 /* Test for overflow by reverse-conversion. */
730 if ((int64) result != val)
731 elog(ERROR, "int8 conversion to int2 is out of range");
733 PG_RETURN_INT16(result);
737 i8tod(PG_FUNCTION_ARGS)
739 int64 val = PG_GETARG_INT64(0);
744 PG_RETURN_FLOAT8(result);
748 * Convert double float to 8-byte integer.
751 dtoi8(PG_FUNCTION_ARGS)
753 float8 val = PG_GETARG_FLOAT8(0);
756 /* Round val to nearest integer (but it's still in float form) */
760 * Does it fit in an int64? Avoid assuming that we have handy
761 * constants defined for the range boundaries, instead test for
762 * overflow by reverse-conversion.
764 result = (int64) val;
766 if ((float8) result != val)
767 elog(ERROR, "Floating point conversion to int8 is out of range");
769 PG_RETURN_INT64(result);
775 text_int8(PG_FUNCTION_ARGS)
777 text *str = PG_GETARG_TEXT_P(0);
782 len = (VARSIZE(str) - VARHDRSZ);
784 memcpy(s, VARDATA(str), len);
787 result = DirectFunctionCall1(int8in, CStringGetDatum(s));
798 int8_text(PG_FUNCTION_ARGS)
800 /* val is int64, but easier to leave it as Datum */
801 Datum val = PG_GETARG_DATUM(0);
806 s = DatumGetCString(DirectFunctionCall1(int8out, val));
809 result = (text *) palloc(VARHDRSZ + len);
811 VARATT_SIZEP(result) = len + VARHDRSZ;
812 memcpy(VARDATA(result), s, len);
816 PG_RETURN_TEXT_P(result);