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