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.23 2000/07/12 22:59:09 petere 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((int) *ptr)) /* skip leading spaces */
72 if (*ptr == '-') /* handle sign */
76 if (!isdigit((int) *ptr)) /* require at least one digit */
77 elog(ERROR, "Bad int8 external representation \"%s\"", str);
78 while (*ptr && isdigit((int) *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.
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 /*----------------------------------------------------------
290 * Arithmetic operators on 64-bit integers.
291 *---------------------------------------------------------*/
294 int8um(PG_FUNCTION_ARGS)
296 int64 val = PG_GETARG_INT64(0);
298 PG_RETURN_INT64(- val);
302 int8pl(PG_FUNCTION_ARGS)
304 int64 val1 = PG_GETARG_INT64(0);
305 int64 val2 = PG_GETARG_INT64(1);
307 PG_RETURN_INT64(val1 + val2);
311 int8mi(PG_FUNCTION_ARGS)
313 int64 val1 = PG_GETARG_INT64(0);
314 int64 val2 = PG_GETARG_INT64(1);
316 PG_RETURN_INT64(val1 - val2);
320 int8mul(PG_FUNCTION_ARGS)
322 int64 val1 = PG_GETARG_INT64(0);
323 int64 val2 = PG_GETARG_INT64(1);
325 PG_RETURN_INT64(val1 * val2);
329 int8div(PG_FUNCTION_ARGS)
331 int64 val1 = PG_GETARG_INT64(0);
332 int64 val2 = PG_GETARG_INT64(1);
334 PG_RETURN_INT64(val1 / val2);
341 int8abs(PG_FUNCTION_ARGS)
343 int64 arg1 = PG_GETARG_INT64(0);
345 PG_RETURN_INT64((arg1 < 0) ? -arg1 : arg1);
352 int8mod(PG_FUNCTION_ARGS)
354 int64 val1 = PG_GETARG_INT64(0);
355 int64 val2 = PG_GETARG_INT64(1);
358 result = val1 / val2;
360 result = val1 - result;
362 PG_RETURN_INT64(result);
369 int8fac(PG_FUNCTION_ARGS)
371 int64 arg1 = PG_GETARG_INT64(0);
378 for (i = arg1, result = 1; i > 0; --i)
381 PG_RETURN_INT64(result);
385 int8larger(PG_FUNCTION_ARGS)
387 int64 val1 = PG_GETARG_INT64(0);
388 int64 val2 = PG_GETARG_INT64(1);
391 result = ((val1 > val2) ? val1 : val2);
393 PG_RETURN_INT64(result);
397 int8smaller(PG_FUNCTION_ARGS)
399 int64 val1 = PG_GETARG_INT64(0);
400 int64 val2 = PG_GETARG_INT64(1);
403 result = ((val1 < val2) ? val1 : val2);
405 PG_RETURN_INT64(result);
409 int84pl(PG_FUNCTION_ARGS)
411 int64 val1 = PG_GETARG_INT64(0);
412 int32 val2 = PG_GETARG_INT32(1);
414 PG_RETURN_INT64(val1 + val2);
418 int84mi(PG_FUNCTION_ARGS)
420 int64 val1 = PG_GETARG_INT64(0);
421 int32 val2 = PG_GETARG_INT32(1);
423 PG_RETURN_INT64(val1 - val2);
427 int84mul(PG_FUNCTION_ARGS)
429 int64 val1 = PG_GETARG_INT64(0);
430 int32 val2 = PG_GETARG_INT32(1);
432 PG_RETURN_INT64(val1 * val2);
436 int84div(PG_FUNCTION_ARGS)
438 int64 val1 = PG_GETARG_INT64(0);
439 int32 val2 = PG_GETARG_INT32(1);
441 PG_RETURN_INT64(val1 / val2);
445 int48pl(PG_FUNCTION_ARGS)
447 int32 val1 = PG_GETARG_INT32(0);
448 int64 val2 = PG_GETARG_INT64(1);
450 PG_RETURN_INT64(val1 + val2);
454 int48mi(PG_FUNCTION_ARGS)
456 int32 val1 = PG_GETARG_INT32(0);
457 int64 val2 = PG_GETARG_INT64(1);
459 PG_RETURN_INT64(val1 - val2);
463 int48mul(PG_FUNCTION_ARGS)
465 int32 val1 = PG_GETARG_INT32(0);
466 int64 val2 = PG_GETARG_INT64(1);
468 PG_RETURN_INT64(val1 * val2);
472 int48div(PG_FUNCTION_ARGS)
474 int32 val1 = PG_GETARG_INT32(0);
475 int64 val2 = PG_GETARG_INT64(1);
477 PG_RETURN_INT64(val1 / val2);
481 /*----------------------------------------------------------
482 * Conversion operators.
483 *---------------------------------------------------------*/
486 int48(PG_FUNCTION_ARGS)
488 int32 val = PG_GETARG_INT32(0);
490 PG_RETURN_INT64((int64) val);
494 int84(PG_FUNCTION_ARGS)
496 int64 val = PG_GETARG_INT64(0);
499 if ((val < INT_MIN) || (val > INT_MAX))
500 elog(ERROR, "int8 conversion to int4 is out of range");
502 result = (int32) val;
504 PG_RETURN_INT32(result);
508 i8tod(PG_FUNCTION_ARGS)
510 int64 val = PG_GETARG_INT64(0);
515 PG_RETURN_FLOAT8(result);
519 * Convert double float to 8-byte integer.
520 * Do a range check before the conversion.
521 * Note that the comparison probably isn't quite right
522 * since we only have ~52 bits of precision in a double float
523 * and so subtracting one from a large number gives the large
524 * number exactly. However, for some reason the comparison below
525 * does the right thing on my i686/linux-rh4.2 box.
526 * - thomas 1998-06-16
529 dtoi8(PG_FUNCTION_ARGS)
531 float8 val = PG_GETARG_FLOAT8(0);
534 if ((val < (-pow(2.0, 63.0) + 1)) || (val > (pow(2.0, 63.0) - 1)))
535 elog(ERROR, "Floating point conversion to int64 is out of range");
537 result = (int64) val;
539 PG_RETURN_INT64(result);
545 text_int8(PG_FUNCTION_ARGS)
547 text *str = PG_GETARG_TEXT_P(0);
552 len = (VARSIZE(str) - VARHDRSZ);
554 memcpy(s, VARDATA(str), len);
557 result = DirectFunctionCall1(int8in, CStringGetDatum(s));
568 int8_text(PG_FUNCTION_ARGS)
570 /* val is int64, but easier to leave it as Datum */
571 Datum val = PG_GETARG_DATUM(0);
576 s = DatumGetCString(DirectFunctionCall1(int8out, val));
579 result = (text *) palloc(VARHDRSZ + len);
581 VARATT_SIZEP(result) = len + VARHDRSZ;
582 memcpy(VARDATA(result), s, len);
586 PG_RETURN_TEXT_P(result);