/*------------------------------------------------------------------------- * * int8.c-- * Internal 64-bit integer operations * *------------------------------------------------------------------------- */ #include /* for sprintf proto, etc. */ #include /* for strtod, etc. */ #include #include #include #include #include #include #include "postgres.h" #include "utils/palloc.h" #define MAXINT8LEN 25 #define USE_LOCAL_CODE 1 #if defined(__alpha) || defined(__GNUC__) #define HAVE_64BIT_INTS 1 #endif #ifndef HAVE_64BIT_INTS typedef char[8] int64; #elif defined(__alpha) typedef long int int64; #define INT64_FORMAT "%ld" #elif defined(__GNUC__) typedef long long int int64; #define INT64_FORMAT "%Ld" #else typedef long int int64; #define INT64_FORMAT "%ld" #endif int64 *int8in(char *str); char *int8out(int64 *val); bool int8eq(int64 *val1, int64 *val2); bool int8ne(int64 *val1, int64 *val2); bool int8lt(int64 *val1, int64 *val2); bool int8gt(int64 *val1, int64 *val2); bool int8le(int64 *val1, int64 *val2); bool int8ge(int64 *val1, int64 *val2); bool int84eq(int64 *val1, int32 val2); bool int84ne(int64 *val1, int32 val2); bool int84lt(int64 *val1, int32 val2); bool int84gt(int64 *val1, int32 val2); bool int84le(int64 *val1, int32 val2); bool int84ge(int64 *val1, int32 val2); int64 *int8um(int64 *val); int64 *int8pl(int64 *val1, int64 *val2); int64 *int8mi(int64 *val1, int64 *val2); int64 *int8mul(int64 *val1, int64 *val2); int64 *int8div(int64 *val1, int64 *val2); int64 *int48(int32 val); int32 int84(int64 *val); #if FALSE int64 *int28(int16 val); int16 int82(int64 *val); #endif float64 i8tod(int64 *val); int64 *dtoi8(float64 val); #if USE_LOCAL_CODE #ifndef PALLOC #define PALLOC(p) palloc(p) #endif #ifndef PALLOCTYPE #define PALLOCTYPE(p) palloc(sizeof(p)) #endif #endif /*********************************************************************** ** ** Routines for 64-bit integers. ** ***********************************************************************/ /*---------------------------------------------------------- * Formatting and conversion routines. *---------------------------------------------------------*/ /* int8in() */ int64 *int8in(char *str) { int64 *result = PALLOCTYPE(int64); #if HAVE_64BIT_INTS if (!PointerIsValid(str)) elog (WARN,"Bad (null) int8 external representation",NULL); if (sscanf(str, INT64_FORMAT, result) != 1) elog(WARN,"Bad int8 external representation '%s'",str); #else elog(WARN,"64-bit integers are not supported",NULL); result = NULL; #endif return(result); } /* int8in() */ /* int8out() */ char *int8out(int64 *val) { char *result; int len; char buf[MAXINT8LEN+1]; #if HAVE_64BIT_INTS if (!PointerIsValid(val)) return(NULL); if ((len = snprintf( buf, MAXINT8LEN, INT64_FORMAT, *val)) < 0) elog (WARN,"Unable to format int8",NULL); result = PALLOC(len+1); strcpy(result, buf); #else elog(WARN,"64-bit integers are not supported",NULL); result = NULL; #endif return( result); } /* int8out() */ /*---------------------------------------------------------- * Relational operators for int8s. *---------------------------------------------------------*/ /* int8relop() * Is val1 relop val2? */ bool int8eq(int64 *val1, int64 *val2) { return(*val1 == *val2); } /* int8eq() */ bool int8ne(int64 *val1, int64 *val2) { return(*val1 != *val2); } /* int8ne() */ bool int8lt(int64 *val1, int64 *val2) { return(*val1 < *val2); } /* int8lt() */ bool int8gt(int64 *val1, int64 *val2) { return(*val1 > *val2); } /* int8gt() */ bool int8le(int64 *val1, int64 *val2) { return(*val1 <= *val2); } /* int8le() */ bool int8ge(int64 *val1, int64 *val2) { return(*val1 >= *val2); } /* int8ge() */ /* int84relop() * Is 64-bit val1 relop 32-bit val2? */ bool int84eq(int64 *val1, int32 val2) { return(*val1 == val2); } /* int84eq() */ bool int84ne(int64 *val1, int32 val2) { return(*val1 != val2); } /* int84ne() */ bool int84lt(int64 *val1, int32 val2) { return(*val1 < val2); } /* int84lt() */ bool int84gt(int64 *val1, int32 val2) { return(*val1 > val2); } /* int84gt() */ bool int84le(int64 *val1, int32 val2) { return(*val1 <= val2); } /* int84le() */ bool int84ge(int64 *val1, int32 val2) { return(*val1 >= val2); } /* int84ge() */ /*---------------------------------------------------------- * Arithmetic operators on 64-bit integers. *---------------------------------------------------------*/ int64 *int8um(int64 *val) { int64 *result = PALLOCTYPE(int64); if (!PointerIsValid(val)) return NULL; *result = (- *val); return(result); } /* int8um() */ int64 *int8pl(int64 *val1, int64 *val2) { int64 *result = PALLOCTYPE(int64); if ((!PointerIsValid(val1)) || (!PointerIsValid(val2))) return NULL; *result = *val1 + *val2; return(result); } /* int8pl() */ int64 *int8mi(int64 *val1, int64 *val2) { int64 *result = PALLOCTYPE(int64); if ((!PointerIsValid(val1)) || (!PointerIsValid(val2))) return NULL; *result = *val1 - *val2; return(result); } /* int8mi() */ int64 *int8mul(int64 *val1, int64 *val2) { int64 *result = PALLOCTYPE(int64); if ((!PointerIsValid(val1)) || (!PointerIsValid(val2))) return NULL; *result = *val1 * *val2; return(result); } /* int8mul() */ int64 *int8div(int64 *val1, int64 *val2) { int64 *result = PALLOCTYPE(int64); if ((!PointerIsValid(val1)) || (!PointerIsValid(val2))) return NULL; *result = *val1 / *val2; return(result); } /* int8div() */ /*---------------------------------------------------------- * Conversion operators. *---------------------------------------------------------*/ int64 *int48(int32 val) { int64 *result = PALLOCTYPE(int64); *result = val; return(result); } /* int48() */ int32 int84(int64 *val) { int32 result; if (!PointerIsValid(val)) elog(WARN,"Invalid (null) int64, can't convert int8 to int4",NULL); if ((*val < INT_MIN) || (*val > INT_MAX)) elog(WARN,"int8 conversion to int4 is out of range",NULL); result = *val; return(result); } /* int84() */ #if FALSE int64 *int28(int16 val) { int64 *result; if (!PointerIsValid(result = PALLOCTYPE(int64))) elog(WARN,"Memory allocation failed, can't convert int8 to int2",NULL); *result = val; return(result); } /* int28() */ int16 int82(int64 *val) { int16 result; if (!PointerIsValid(val)) elog(WARN,"Invalid (null) int8, can't convert to int2",NULL); result = *val; return(result); } /* int82() */ #endif float64 i8tod(int64 *val) { float64 result = PALLOCTYPE(float64data); *result = *val; return(result); } /* i8tod() */ int64 *dtoi8(float64 val) { int64 *result = PALLOCTYPE(int64); if ((*val < (-pow(2,64)+1)) || (*val > (pow(2,64)-1))) elog(WARN,"Floating point conversion to int64 is out of range",NULL); *result = *val; return(result); } /* dtoi8() */