1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
/*
* libtu/np-conv.h
*
* Copyright (c) Tuomo Valkonen 1999-2002.
*
* You may distribute and modify this library under the terms of either
* the Clarified Artistic License or the GNU LGPL, version 2.1 or later.
*/
#include <math.h>
#ifdef NP_SIMPLE_IMPL
#define FN_NUM_TO_SIGNED(T, UMAX, MAX, MIN) \
static int num_to_##T(T *ret, const NPNum *num, bool allow_uns_big) \
{ \
if(num->type!=NPNUM_INT) \
return E_TOKZ_NOTINT; \
\
if(!num->negative){ \
*ret=num->ival; \
if(allow_uns_big?num->ival>UMAX:num->ival>MAX) \
return E_TOKZ_RANGE; \
}else{ \
*ret=-num->ival; \
if(num->ival>-(ulong)MIN) \
return E_TOKZ_RANGE; \
} \
return 0; \
}
#define FN_NUM_TO_UNSIGNED(T, UMAX, MIN) \
static int num_to_##T(T *ret, const NPNum *num, bool allow_neg) \
{ \
if(num->type!=NPNUM_INT) \
return E_TOKZ_NOTINT; \
\
if(!num->negative){ \
*ret=num->ival; \
if(num->ival>UMAX) \
return E_TOKZ_RANGE; \
}else{ \
*ret=-num->ival; \
if(!allow_neg || num->ival>(ulong)-MIN) \
return E_TOKZ_RANGE; \
} \
return 0; \
}
#define FN_NUM_TO_FLOAT(T, POW) \
static int num_to_##T(T *ret, const NPNum *num) \
{ \
*ret=(num->negative?-num->fval:num->fval); \
return 0; \
}
#else /* NP_SIMPLE_IMPL */
#define FN_NUM_TO_SIGNED(T, UMAX, MAX, MIN) \
static int num_to_##T(T *ret, const NPNum *num, bool allow_uns_big) \
{ \
if(num->exponent) \
return E_TOKZ_NOTINT; \
if(num->nmantissa>0) \
return E_TOKZ_RANGE; \
\
if(!num->negative){ \
*ret=num->mantissa[0]; \
if(allow_uns_big?num->mantissa[0]>UMAX:num->mantissa[0]>MAX) \
return E_TOKZ_RANGE; \
}else{ \
*ret=-num->mantissa[0]; \
if(num->mantissa[0]>-(ulong)MIN) \
return E_TOKZ_RANGE; \
} \
return 0; \
}
#define FN_NUM_TO_UNSIGNED(T, UMAX, MIN) \
static int num_to_##T(T *ret, const NPNum *num, bool allow_neg) \
{ \
if(num->exponent) \
return E_TOKZ_NOTINT; \
if(num->nmantissa>0) \
return E_TOKZ_RANGE; \
\
if(!num->negative){ \
*ret=num->mantissa[0]; \
if(num->mantissa[0]>UMAX) \
return E_TOKZ_RANGE; \
}else{ \
*ret=-num->mantissa[0]; \
if(!allow_neg || num->mantissa[0]>(ulong)-MIN) \
return E_TOKZ_RANGE; \
} \
return 0; \
}
#define FN_NUM_TO_FLOAT(T, POW) \
static int num_to_##T(T *ret, const NPNum *num) \
{ \
T d=0; \
int i; \
\
for(i=num->nmantissa;i>=0;i--) \
d=d*(T)(ULONG_MAX+1.0)+num->mantissa[i]; \
\
d*=POW(num->base, num->exponent); \
*ret=d; \
\
return 0; \
}
#endif /* NP_SIMPLE_IMPL */
FN_NUM_TO_SIGNED(long, ULONG_MAX, LONG_MAX, LONG_MIN)
FN_NUM_TO_SIGNED(char, UCHAR_MAX, CHAR_MAX, CHAR_MIN)
FN_NUM_TO_FLOAT(double, pow)
#undef NEG
|