1 /*-------------------------------------------------------------------------
4 * Internal 64-bit integer operations
6 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.21 2000/06/14 18:17:44 petere Exp $
12 *-------------------------------------------------------------------------
25 #include "utils/int8.h"
27 /* this should be set in config.h, but just in case it wasn't: */
29 #define INT64_FORMAT "%ld"
35 #define INT_MAX (0x7FFFFFFFL)
38 #define INT_MIN (-INT_MAX-1)
41 #define SHRT_MAX (0x7FFF)
44 #define SHRT_MIN (-SHRT_MAX-1)
48 /***********************************************************************
50 ** Routines for 64-bit integers.
52 ***********************************************************************/
54 /*----------------------------------------------------------
55 * Formatting and conversion routines.
56 *---------------------------------------------------------*/
61 int8in(PG_FUNCTION_ARGS)
63 char *str = PG_GETARG_CSTRING(0);
70 * Do our own scan, rather than relying on sscanf which might be
71 * broken for long long.
73 while (*ptr && isspace((int) *ptr)) /* skip leading spaces */
75 if (*ptr == '-') /* handle sign */
79 if (!isdigit((int) *ptr)) /* require at least one digit */
80 elog(ERROR, "Bad int8 external representation \"%s\"", str);
81 while (*ptr && isdigit((int) *ptr)) /* process digits */
83 int64 newtmp = tmp * 10 + (*ptr++ - '0');
85 if ((newtmp / 10) != tmp) /* overflow? */
86 elog(ERROR, "int8 value out of range: \"%s\"", str);
89 if (*ptr) /* trailing junk? */
90 elog(ERROR, "Bad int8 external representation \"%s\"", str);
92 result = (sign < 0) ? -tmp : tmp;
94 PG_RETURN_INT64(result);
101 int8out(PG_FUNCTION_ARGS)
103 int64 val = PG_GETARG_INT64(0);
106 char buf[MAXINT8LEN + 1];
108 if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, val)) < 0)
109 elog(ERROR, "Unable to format int8");
111 result = pstrdup(buf);
112 PG_RETURN_CSTRING(result);
116 /*----------------------------------------------------------
117 * Relational operators for int8s.
118 *---------------------------------------------------------*/
121 * Is val1 relop val2?
124 int8eq(PG_FUNCTION_ARGS)
126 int64 val1 = PG_GETARG_INT64(0);
127 int64 val2 = PG_GETARG_INT64(1);
129 PG_RETURN_BOOL(val1 == val2);
133 int8ne(PG_FUNCTION_ARGS)
135 int64 val1 = PG_GETARG_INT64(0);
136 int64 val2 = PG_GETARG_INT64(1);
138 PG_RETURN_BOOL(val1 != val2);
142 int8lt(PG_FUNCTION_ARGS)
144 int64 val1 = PG_GETARG_INT64(0);
145 int64 val2 = PG_GETARG_INT64(1);
147 PG_RETURN_BOOL(val1 < val2);
151 int8gt(PG_FUNCTION_ARGS)
153 int64 val1 = PG_GETARG_INT64(0);
154 int64 val2 = PG_GETARG_INT64(1);
156 PG_RETURN_BOOL(val1 > val2);
160 int8le(PG_FUNCTION_ARGS)
162 int64 val1 = PG_GETARG_INT64(0);
163 int64 val2 = PG_GETARG_INT64(1);
165 PG_RETURN_BOOL(val1 <= val2);
169 int8ge(PG_FUNCTION_ARGS)
171 int64 val1 = PG_GETARG_INT64(0);
172 int64 val2 = PG_GETARG_INT64(1);
174 PG_RETURN_BOOL(val1 >= val2);
178 * Is 64-bit val1 relop 32-bit val2?
181 int84eq(PG_FUNCTION_ARGS)
183 int64 val1 = PG_GETARG_INT64(0);
184 int32 val2 = PG_GETARG_INT32(1);
186 PG_RETURN_BOOL(val1 == val2);
190 int84ne(PG_FUNCTION_ARGS)
192 int64 val1 = PG_GETARG_INT64(0);
193 int32 val2 = PG_GETARG_INT32(1);
195 PG_RETURN_BOOL(val1 != val2);
199 int84lt(PG_FUNCTION_ARGS)
201 int64 val1 = PG_GETARG_INT64(0);
202 int32 val2 = PG_GETARG_INT32(1);
204 PG_RETURN_BOOL(val1 < val2);
208 int84gt(PG_FUNCTION_ARGS)
210 int64 val1 = PG_GETARG_INT64(0);
211 int32 val2 = PG_GETARG_INT32(1);
213 PG_RETURN_BOOL(val1 > val2);
217 int84le(PG_FUNCTION_ARGS)
219 int64 val1 = PG_GETARG_INT64(0);
220 int32 val2 = PG_GETARG_INT32(1);
222 PG_RETURN_BOOL(val1 <= val2);
226 int84ge(PG_FUNCTION_ARGS)
228 int64 val1 = PG_GETARG_INT64(0);
229 int32 val2 = PG_GETARG_INT32(1);
231 PG_RETURN_BOOL(val1 >= val2);
235 * Is 32-bit val1 relop 64-bit val2?
238 int48eq(PG_FUNCTION_ARGS)
240 int32 val1 = PG_GETARG_INT32(0);
241 int64 val2 = PG_GETARG_INT64(1);
243 PG_RETURN_BOOL(val1 == val2);
247 int48ne(PG_FUNCTION_ARGS)
249 int32 val1 = PG_GETARG_INT32(0);
250 int64 val2 = PG_GETARG_INT64(1);
252 PG_RETURN_BOOL(val1 != val2);
256 int48lt(PG_FUNCTION_ARGS)
258 int32 val1 = PG_GETARG_INT32(0);
259 int64 val2 = PG_GETARG_INT64(1);
261 PG_RETURN_BOOL(val1 < val2);
265 int48gt(PG_FUNCTION_ARGS)
267 int32 val1 = PG_GETARG_INT32(0);
268 int64 val2 = PG_GETARG_INT64(1);
270 PG_RETURN_BOOL(val1 > val2);
274 int48le(PG_FUNCTION_ARGS)
276 int32 val1 = PG_GETARG_INT32(0);
277 int64 val2 = PG_GETARG_INT64(1);
279 PG_RETURN_BOOL(val1 <= val2);
283 int48ge(PG_FUNCTION_ARGS)
285 int32 val1 = PG_GETARG_INT32(0);
286 int64 val2 = PG_GETARG_INT64(1);
288 PG_RETURN_BOOL(val1 >= val2);
292 /*----------------------------------------------------------
293 * Arithmetic operators on 64-bit integers.
294 *---------------------------------------------------------*/
297 int8um(PG_FUNCTION_ARGS)
299 int64 val = PG_GETARG_INT64(0);
301 PG_RETURN_INT64(- val);
305 int8pl(PG_FUNCTION_ARGS)
307 int64 val1 = PG_GETARG_INT64(0);
308 int64 val2 = PG_GETARG_INT64(1);
310 PG_RETURN_INT64(val1 + val2);
314 int8mi(PG_FUNCTION_ARGS)
316 int64 val1 = PG_GETARG_INT64(0);
317 int64 val2 = PG_GETARG_INT64(1);
319 PG_RETURN_INT64(val1 - val2);
323 int8mul(PG_FUNCTION_ARGS)
325 int64 val1 = PG_GETARG_INT64(0);
326 int64 val2 = PG_GETARG_INT64(1);
328 PG_RETURN_INT64(val1 * val2);
332 int8div(PG_FUNCTION_ARGS)
334 int64 val1 = PG_GETARG_INT64(0);
335 int64 val2 = PG_GETARG_INT64(1);
337 PG_RETURN_INT64(val1 / val2);
344 int8abs(PG_FUNCTION_ARGS)
346 int64 arg1 = PG_GETARG_INT64(0);
348 PG_RETURN_INT64((arg1 < 0) ? -arg1 : arg1);
355 int8mod(PG_FUNCTION_ARGS)
357 int64 val1 = PG_GETARG_INT64(0);
358 int64 val2 = PG_GETARG_INT64(1);
361 result = val1 / val2;
363 result = val1 - result;
365 PG_RETURN_INT64(result);
372 int8fac(PG_FUNCTION_ARGS)
374 int64 arg1 = PG_GETARG_INT64(0);
381 for (i = arg1, result = 1; i > 0; --i)
384 PG_RETURN_INT64(result);
388 int8larger(PG_FUNCTION_ARGS)
390 int64 val1 = PG_GETARG_INT64(0);
391 int64 val2 = PG_GETARG_INT64(1);
394 result = ((val1 > val2) ? val1 : val2);
396 PG_RETURN_INT64(result);
400 int8smaller(PG_FUNCTION_ARGS)
402 int64 val1 = PG_GETARG_INT64(0);
403 int64 val2 = PG_GETARG_INT64(1);
406 result = ((val1 < val2) ? val1 : val2);
408 PG_RETURN_INT64(result);
412 int84pl(PG_FUNCTION_ARGS)
414 int64 val1 = PG_GETARG_INT64(0);
415 int32 val2 = PG_GETARG_INT32(1);
417 PG_RETURN_INT64(val1 + val2);
421 int84mi(PG_FUNCTION_ARGS)
423 int64 val1 = PG_GETARG_INT64(0);
424 int32 val2 = PG_GETARG_INT32(1);
426 PG_RETURN_INT64(val1 - val2);
430 int84mul(PG_FUNCTION_ARGS)
432 int64 val1 = PG_GETARG_INT64(0);
433 int32 val2 = PG_GETARG_INT32(1);
435 PG_RETURN_INT64(val1 * val2);
439 int84div(PG_FUNCTION_ARGS)
441 int64 val1 = PG_GETARG_INT64(0);
442 int32 val2 = PG_GETARG_INT32(1);
444 PG_RETURN_INT64(val1 / val2);
448 int48pl(PG_FUNCTION_ARGS)
450 int32 val1 = PG_GETARG_INT32(0);
451 int64 val2 = PG_GETARG_INT64(1);
453 PG_RETURN_INT64(val1 + val2);
457 int48mi(PG_FUNCTION_ARGS)
459 int32 val1 = PG_GETARG_INT32(0);
460 int64 val2 = PG_GETARG_INT64(1);
462 PG_RETURN_INT64(val1 - val2);
466 int48mul(PG_FUNCTION_ARGS)
468 int32 val1 = PG_GETARG_INT32(0);
469 int64 val2 = PG_GETARG_INT64(1);
471 PG_RETURN_INT64(val1 * val2);
475 int48div(PG_FUNCTION_ARGS)
477 int32 val1 = PG_GETARG_INT32(0);
478 int64 val2 = PG_GETARG_INT64(1);
480 PG_RETURN_INT64(val1 / val2);
484 /*----------------------------------------------------------
485 * Conversion operators.
486 *---------------------------------------------------------*/
489 int48(PG_FUNCTION_ARGS)
491 int32 val = PG_GETARG_INT32(0);
493 PG_RETURN_INT64((int64) val);
497 int84(PG_FUNCTION_ARGS)
499 int64 val = PG_GETARG_INT64(0);
502 if ((val < INT_MIN) || (val > INT_MAX))
503 elog(ERROR, "int8 conversion to int4 is out of range");
505 result = (int32) val;
507 PG_RETURN_INT32(result);
511 i8tod(PG_FUNCTION_ARGS)
513 int64 val = PG_GETARG_INT64(0);
518 PG_RETURN_FLOAT8(result);
522 * Convert double float to 8-byte integer.
523 * Do a range check before the conversion.
524 * Note that the comparison probably isn't quite right
525 * since we only have ~52 bits of precision in a double float
526 * and so subtracting one from a large number gives the large
527 * number exactly. However, for some reason the comparison below
528 * does the right thing on my i686/linux-rh4.2 box.
529 * - thomas 1998-06-16
532 dtoi8(PG_FUNCTION_ARGS)
534 float8 val = PG_GETARG_FLOAT8(0);
537 if ((val < (-pow(2.0, 63.0) + 1)) || (val > (pow(2.0, 63.0) - 1)))
538 elog(ERROR, "Floating point conversion to int64 is out of range");
540 result = (int64) val;
542 PG_RETURN_INT64(result);
548 text_int8(PG_FUNCTION_ARGS)
550 text *str = PG_GETARG_TEXT_P(0);
555 len = (VARSIZE(str) - VARHDRSZ);
557 memcpy(s, VARDATA(str), len);
560 result = DirectFunctionCall1(int8in, CStringGetDatum(s));
571 int8_text(PG_FUNCTION_ARGS)
573 /* val is int64, but easier to leave it as Datum */
574 Datum val = PG_GETARG_DATUM(0);
579 s = DatumGetCString(DirectFunctionCall1(int8out, val));
582 result = (text *) palloc(VARHDRSZ + len);
584 VARSIZE(result) = len + VARHDRSZ;
585 memcpy(VARDATA(result), s, len);
589 PG_RETURN_TEXT_P(result);