]> git.decadent.org.uk Git - ion3.git/blob - libtu/np-conv.h
[svn-inject] Installing original source of ion3
[ion3.git] / libtu / np-conv.h
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