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.29 2001/03/22 03:59:51 momjian Exp $
12 *-------------------------------------------------------------------------
22 #include "utils/int8.h"
24 /* this should be set in config.h, but just in case it wasn't: */
26 #define INT64_FORMAT "%ld"
32 #define INT_MAX (0x7FFFFFFFL)
35 #define INT_MIN (-INT_MAX-1)
38 #define SHRT_MAX (0x7FFF)
41 #define SHRT_MIN (-SHRT_MAX-1)
45 /***********************************************************************
47 ** Routines for 64-bit integers.
49 ***********************************************************************/
51 /*----------------------------------------------------------
52 * Formatting and conversion routines.
53 *---------------------------------------------------------*/
58 int8in(PG_FUNCTION_ARGS)
60 char *str = PG_GETARG_CSTRING(0);
67 * Do our own scan, rather than relying on sscanf which might be
68 * broken for long long.
70 while (*ptr && isspace((unsigned char) *ptr)) /* skip leading spaces */
72 if (*ptr == '-') /* handle sign */
76 if (!isdigit((unsigned char) *ptr)) /* require at least one digit */
77 elog(ERROR, "Bad int8 external representation \"%s\"", str);
78 while (*ptr && isdigit((unsigned char) *ptr)) /* process digits */
80 int64 newtmp = tmp * 10 + (*ptr++ - '0');
82 if ((newtmp / 10) != tmp) /* overflow? */
83 elog(ERROR, "int8 value out of range: \"%s\"", str);
86 if (*ptr) /* trailing junk? */
87 elog(ERROR, "Bad int8 external representation \"%s\"", str);
89 result = (sign < 0) ? -tmp : tmp;
91 PG_RETURN_INT64(result);
98 int8out(PG_FUNCTION_ARGS)
100 int64 val = PG_GETARG_INT64(0);
103 char buf[MAXINT8LEN + 1];
105 if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, val)) < 0)
106 elog(ERROR, "Unable to format int8");
108 result = pstrdup(buf);
109 PG_RETURN_CSTRING(result);
113 /*----------------------------------------------------------
114 * Relational operators for int8s, including cross-data-type comparisons.
115 *---------------------------------------------------------*/
118 * Is val1 relop val2?
121 int8eq(PG_FUNCTION_ARGS)
123 int64 val1 = PG_GETARG_INT64(0);
124 int64 val2 = PG_GETARG_INT64(1);
126 PG_RETURN_BOOL(val1 == val2);
130 int8ne(PG_FUNCTION_ARGS)
132 int64 val1 = PG_GETARG_INT64(0);
133 int64 val2 = PG_GETARG_INT64(1);
135 PG_RETURN_BOOL(val1 != val2);
139 int8lt(PG_FUNCTION_ARGS)
141 int64 val1 = PG_GETARG_INT64(0);
142 int64 val2 = PG_GETARG_INT64(1);
144 PG_RETURN_BOOL(val1 < val2);
148 int8gt(PG_FUNCTION_ARGS)
150 int64 val1 = PG_GETARG_INT64(0);
151 int64 val2 = PG_GETARG_INT64(1);
153 PG_RETURN_BOOL(val1 > val2);
157 int8le(PG_FUNCTION_ARGS)
159 int64 val1 = PG_GETARG_INT64(0);
160 int64 val2 = PG_GETARG_INT64(1);
162 PG_RETURN_BOOL(val1 <= val2);
166 int8ge(PG_FUNCTION_ARGS)
168 int64 val1 = PG_GETARG_INT64(0);
169 int64 val2 = PG_GETARG_INT64(1);
171 PG_RETURN_BOOL(val1 >= val2);
175 * Is 64-bit val1 relop 32-bit val2?
178 int84eq(PG_FUNCTION_ARGS)
180 int64 val1 = PG_GETARG_INT64(0);
181 int32 val2 = PG_GETARG_INT32(1);
183 PG_RETURN_BOOL(val1 == val2);
187 int84ne(PG_FUNCTION_ARGS)
189 int64 val1 = PG_GETARG_INT64(0);
190 int32 val2 = PG_GETARG_INT32(1);
192 PG_RETURN_BOOL(val1 != val2);
196 int84lt(PG_FUNCTION_ARGS)
198 int64 val1 = PG_GETARG_INT64(0);
199 int32 val2 = PG_GETARG_INT32(1);
201 PG_RETURN_BOOL(val1 < val2);
205 int84gt(PG_FUNCTION_ARGS)
207 int64 val1 = PG_GETARG_INT64(0);
208 int32 val2 = PG_GETARG_INT32(1);
210 PG_RETURN_BOOL(val1 > val2);
214 int84le(PG_FUNCTION_ARGS)
216 int64 val1 = PG_GETARG_INT64(0);
217 int32 val2 = PG_GETARG_INT32(1);
219 PG_RETURN_BOOL(val1 <= val2);
223 int84ge(PG_FUNCTION_ARGS)
225 int64 val1 = PG_GETARG_INT64(0);
226 int32 val2 = PG_GETARG_INT32(1);
228 PG_RETURN_BOOL(val1 >= val2);
232 * Is 32-bit val1 relop 64-bit val2?
235 int48eq(PG_FUNCTION_ARGS)
237 int32 val1 = PG_GETARG_INT32(0);
238 int64 val2 = PG_GETARG_INT64(1);
240 PG_RETURN_BOOL(val1 == val2);
244 int48ne(PG_FUNCTION_ARGS)
246 int32 val1 = PG_GETARG_INT32(0);
247 int64 val2 = PG_GETARG_INT64(1);
249 PG_RETURN_BOOL(val1 != val2);
253 int48lt(PG_FUNCTION_ARGS)
255 int32 val1 = PG_GETARG_INT32(0);
256 int64 val2 = PG_GETARG_INT64(1);
258 PG_RETURN_BOOL(val1 < val2);
262 int48gt(PG_FUNCTION_ARGS)
264 int32 val1 = PG_GETARG_INT32(0);
265 int64 val2 = PG_GETARG_INT64(1);
267 PG_RETURN_BOOL(val1 > val2);
271 int48le(PG_FUNCTION_ARGS)
273 int32 val1 = PG_GETARG_INT32(0);
274 int64 val2 = PG_GETARG_INT64(1);
276 PG_RETURN_BOOL(val1 <= val2);
280 int48ge(PG_FUNCTION_ARGS)
282 int32 val1 = PG_GETARG_INT32(0);
283 int64 val2 = PG_GETARG_INT64(1);
285 PG_RETURN_BOOL(val1 >= val2);
289 * Is 64-bit val1 relop 16-bit val2?
292 int82eq(PG_FUNCTION_ARGS)
294 int64 val1 = PG_GETARG_INT64(0);
295 int16 val2 = PG_GETARG_INT16(1);
297 PG_RETURN_BOOL(val1 == val2);
301 int82ne(PG_FUNCTION_ARGS)
303 int64 val1 = PG_GETARG_INT64(0);
304 int16 val2 = PG_GETARG_INT16(1);
306 PG_RETURN_BOOL(val1 != val2);
310 int82lt(PG_FUNCTION_ARGS)
312 int64 val1 = PG_GETARG_INT64(0);
313 int16 val2 = PG_GETARG_INT16(1);
315 PG_RETURN_BOOL(val1 < val2);
319 int82gt(PG_FUNCTION_ARGS)
321 int64 val1 = PG_GETARG_INT64(0);
322 int16 val2 = PG_GETARG_INT16(1);
324 PG_RETURN_BOOL(val1 > val2);
328 int82le(PG_FUNCTION_ARGS)
330 int64 val1 = PG_GETARG_INT64(0);
331 int16 val2 = PG_GETARG_INT16(1);
333 PG_RETURN_BOOL(val1 <= val2);
337 int82ge(PG_FUNCTION_ARGS)
339 int64 val1 = PG_GETARG_INT64(0);
340 int16 val2 = PG_GETARG_INT16(1);
342 PG_RETURN_BOOL(val1 >= val2);
346 * Is 16-bit val1 relop 64-bit val2?
349 int28eq(PG_FUNCTION_ARGS)
351 int16 val1 = PG_GETARG_INT16(0);
352 int64 val2 = PG_GETARG_INT64(1);
354 PG_RETURN_BOOL(val1 == val2);
358 int28ne(PG_FUNCTION_ARGS)
360 int16 val1 = PG_GETARG_INT16(0);
361 int64 val2 = PG_GETARG_INT64(1);
363 PG_RETURN_BOOL(val1 != val2);
367 int28lt(PG_FUNCTION_ARGS)
369 int16 val1 = PG_GETARG_INT16(0);
370 int64 val2 = PG_GETARG_INT64(1);
372 PG_RETURN_BOOL(val1 < val2);
376 int28gt(PG_FUNCTION_ARGS)
378 int16 val1 = PG_GETARG_INT16(0);
379 int64 val2 = PG_GETARG_INT64(1);
381 PG_RETURN_BOOL(val1 > val2);
385 int28le(PG_FUNCTION_ARGS)
387 int16 val1 = PG_GETARG_INT16(0);
388 int64 val2 = PG_GETARG_INT64(1);
390 PG_RETURN_BOOL(val1 <= val2);
394 int28ge(PG_FUNCTION_ARGS)
396 int16 val1 = PG_GETARG_INT16(0);
397 int64 val2 = PG_GETARG_INT64(1);
399 PG_RETURN_BOOL(val1 >= val2);
403 /*----------------------------------------------------------
404 * Arithmetic operators on 64-bit integers.
405 *---------------------------------------------------------*/
408 int8um(PG_FUNCTION_ARGS)
410 int64 val = PG_GETARG_INT64(0);
412 PG_RETURN_INT64(-val);
416 int8pl(PG_FUNCTION_ARGS)
418 int64 val1 = PG_GETARG_INT64(0);
419 int64 val2 = PG_GETARG_INT64(1);
421 PG_RETURN_INT64(val1 + val2);
425 int8mi(PG_FUNCTION_ARGS)
427 int64 val1 = PG_GETARG_INT64(0);
428 int64 val2 = PG_GETARG_INT64(1);
430 PG_RETURN_INT64(val1 - val2);
434 int8mul(PG_FUNCTION_ARGS)
436 int64 val1 = PG_GETARG_INT64(0);
437 int64 val2 = PG_GETARG_INT64(1);
439 PG_RETURN_INT64(val1 * val2);
443 int8div(PG_FUNCTION_ARGS)
445 int64 val1 = PG_GETARG_INT64(0);
446 int64 val2 = PG_GETARG_INT64(1);
448 PG_RETURN_INT64(val1 / val2);
455 int8abs(PG_FUNCTION_ARGS)
457 int64 arg1 = PG_GETARG_INT64(0);
459 PG_RETURN_INT64((arg1 < 0) ? -arg1 : arg1);
466 int8mod(PG_FUNCTION_ARGS)
468 int64 val1 = PG_GETARG_INT64(0);
469 int64 val2 = PG_GETARG_INT64(1);
472 result = val1 / val2;
474 result = val1 - result;
476 PG_RETURN_INT64(result);
483 int8fac(PG_FUNCTION_ARGS)
485 int64 arg1 = PG_GETARG_INT64(0);
492 for (i = arg1, result = 1; i > 0; --i)
495 PG_RETURN_INT64(result);
499 int8larger(PG_FUNCTION_ARGS)
501 int64 val1 = PG_GETARG_INT64(0);
502 int64 val2 = PG_GETARG_INT64(1);
505 result = ((val1 > val2) ? val1 : val2);
507 PG_RETURN_INT64(result);
511 int8smaller(PG_FUNCTION_ARGS)
513 int64 val1 = PG_GETARG_INT64(0);
514 int64 val2 = PG_GETARG_INT64(1);
517 result = ((val1 < val2) ? val1 : val2);
519 PG_RETURN_INT64(result);
523 int84pl(PG_FUNCTION_ARGS)
525 int64 val1 = PG_GETARG_INT64(0);
526 int32 val2 = PG_GETARG_INT32(1);
528 PG_RETURN_INT64(val1 + val2);
532 int84mi(PG_FUNCTION_ARGS)
534 int64 val1 = PG_GETARG_INT64(0);
535 int32 val2 = PG_GETARG_INT32(1);
537 PG_RETURN_INT64(val1 - val2);
541 int84mul(PG_FUNCTION_ARGS)
543 int64 val1 = PG_GETARG_INT64(0);
544 int32 val2 = PG_GETARG_INT32(1);
546 PG_RETURN_INT64(val1 * val2);
550 int84div(PG_FUNCTION_ARGS)
552 int64 val1 = PG_GETARG_INT64(0);
553 int32 val2 = PG_GETARG_INT32(1);
555 PG_RETURN_INT64(val1 / val2);
559 int48pl(PG_FUNCTION_ARGS)
561 int32 val1 = PG_GETARG_INT32(0);
562 int64 val2 = PG_GETARG_INT64(1);
564 PG_RETURN_INT64(val1 + val2);
568 int48mi(PG_FUNCTION_ARGS)
570 int32 val1 = PG_GETARG_INT32(0);
571 int64 val2 = PG_GETARG_INT64(1);
573 PG_RETURN_INT64(val1 - val2);
577 int48mul(PG_FUNCTION_ARGS)
579 int32 val1 = PG_GETARG_INT32(0);
580 int64 val2 = PG_GETARG_INT64(1);
582 PG_RETURN_INT64(val1 * val2);
586 int48div(PG_FUNCTION_ARGS)
588 int32 val1 = PG_GETARG_INT32(0);
589 int64 val2 = PG_GETARG_INT64(1);
591 PG_RETURN_INT64(val1 / val2);
594 /* Binary arithmetics
596 * int8and - returns arg1 & arg2
597 * int8or - returns arg1 | arg2
598 * int8xor - returns arg1 # arg2
599 * int8not - returns ~arg1
600 * int8shl - returns arg1 << arg2
601 * int8shr - returns arg1 >> arg2
605 int8and(PG_FUNCTION_ARGS)
607 int64 arg1 = PG_GETARG_INT64(0);
608 int64 arg2 = PG_GETARG_INT64(1);
610 PG_RETURN_INT64(arg1 & arg2);
614 int8or(PG_FUNCTION_ARGS)
616 int64 arg1 = PG_GETARG_INT64(0);
617 int64 arg2 = PG_GETARG_INT64(1);
619 PG_RETURN_INT64(arg1 | arg2);
623 int8xor(PG_FUNCTION_ARGS)
625 int64 arg1 = PG_GETARG_INT64(0);
626 int64 arg2 = PG_GETARG_INT64(1);
628 PG_RETURN_INT64(arg1 ^ arg2);
632 int8not(PG_FUNCTION_ARGS)
634 int64 arg1 = PG_GETARG_INT64(0);
636 PG_RETURN_INT64(~arg1);
640 int8shl(PG_FUNCTION_ARGS)
642 int64 arg1 = PG_GETARG_INT64(0);
643 int32 arg2 = PG_GETARG_INT32(1);
645 PG_RETURN_INT64(arg1 << arg2);
649 int8shr(PG_FUNCTION_ARGS)
651 int64 arg1 = PG_GETARG_INT64(0);
652 int32 arg2 = PG_GETARG_INT32(1);
654 PG_RETURN_INT64(arg1 >> arg2);
657 /*----------------------------------------------------------
658 * Conversion operators.
659 *---------------------------------------------------------*/
662 int48(PG_FUNCTION_ARGS)
664 int32 val = PG_GETARG_INT32(0);
666 PG_RETURN_INT64((int64) val);
670 int84(PG_FUNCTION_ARGS)
672 int64 val = PG_GETARG_INT64(0);
675 if ((val < INT_MIN) || (val > INT_MAX))
676 elog(ERROR, "int8 conversion to int4 is out of range");
678 result = (int32) val;
680 PG_RETURN_INT32(result);
684 i8tod(PG_FUNCTION_ARGS)
686 int64 val = PG_GETARG_INT64(0);
691 PG_RETURN_FLOAT8(result);
695 * Convert double float to 8-byte integer.
698 dtoi8(PG_FUNCTION_ARGS)
700 float8 val = PG_GETARG_FLOAT8(0);
703 /* Round val to nearest integer (but it's still in float form) */
707 * Does it fit in an int64? Avoid assuming that we have handy
708 * constants defined for the range boundaries, instead test for
709 * overflow by reverse-conversion.
711 result = (int64) val;
713 if ((float8) result != val)
714 elog(ERROR, "Floating point conversion to int8 is out of range");
716 PG_RETURN_INT64(result);
722 text_int8(PG_FUNCTION_ARGS)
724 text *str = PG_GETARG_TEXT_P(0);
729 len = (VARSIZE(str) - VARHDRSZ);
731 memcpy(s, VARDATA(str), len);
734 result = DirectFunctionCall1(int8in, CStringGetDatum(s));
745 int8_text(PG_FUNCTION_ARGS)
747 /* val is int64, but easier to leave it as Datum */
748 Datum val = PG_GETARG_DATUM(0);
753 s = DatumGetCString(DirectFunctionCall1(int8out, val));
756 result = (text *) palloc(VARHDRSZ + len);
758 VARATT_SIZEP(result) = len + VARHDRSZ;
759 memcpy(VARDATA(result), s, len);
763 PG_RETURN_TEXT_P(result);