np/np-conv.h

changeset 60
a4033700e35c
child 62
aae5facf9fc5
equal deleted inserted replaced
59:d8ecbeda7683 60:a4033700e35c
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

mercurial