4 * Copyright (c) Tuomo Valkonen 1999-2002.
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.
10 #define MAX_MANTISSA 10 /* should be enough for our needs */
11 #define ULONG_SIZE (sizeof(ulong)*8)
20 typedef struct _NPNum
{
28 #define NUM_INIT {0, 0, 0, 0.0, 0}
30 static int npnum_mulbase_add(NPNum
*num
, long base
, long v
)
32 double iold
=num
->ival
;
34 num
->fval
=num
->fval
*base
+(double)v
;
39 num
->type
=NPNUM_FLOAT
;
46 #else /* NP_SIMPLE_IMPL */
48 typedef struct _NPNum
{
49 unsigned char nmantissa
;
53 ulong mantissa
[MAX_MANTISSA
];
57 #define NUM_INIT {0, 0, 0, 0, {0,}, 0}
59 #define ADD_EXP(NUM, X) (NUM)->exponent+=(X);
61 #if defined(__GNUG__) && defined(i386) && !defined(NP_NO_I386_ASM)
65 static int npnum_mulbase_add(NPNum
*num
, long base
, long v
)
73 for(i
=num
->nmantissa
;i
>=0;i
--){
76 : "=a" (num
->mantissa
[i
]), "=d" (overflow
)
77 : "0" (num
->mantissa
[i
]), "1" (0), "q" (base
)
83 if(val
<ULONG_MAX
/base
){
88 for(j
=0; j
<base
; j
++){
98 if(i
==num
->nmantissa
){
99 if(num
->nmantissa
==MAX_MANTISSA
)
100 return E_TOKZ_TOOBIG
;
103 num
->mantissa
[i
+1]+=overflow
;
113 #endif /* NP_SIMPLE_IMPL */
119 static bool is_end(int c
)
121 /* oops... EOF was missing */
122 return (c
==EOF
|| (c
!='.' && ispunct(c
)) || isspace(c
) || iscntrl(c
));
129 static int parse_exponent(NPNum
*num
, Tokenizer
*tokz
, int c
)
137 if(c
=='-' || c
=='+'){
158 #ifndef NP_SIMPLE_IMPL
161 num
->fval
*=pow(num
->base
, exp
);
167 static int parse_number(NPNum
*num
, Tokenizer
*tokz
, int c
)
173 #ifdef NP_SIMPLE_IMPL
177 if(c
=='-' || c
=='+'){
188 if(c
=='x' || c
=='X'){
191 }else if(c
=='b' || c
=='B'){
194 }else if('0'<=c
&& c
<='7'){
204 if((c
=='e' || c
=='E') && dm
!=0){
209 tmp
=parse_exponent(num
, tokz
, c
);
226 #ifdef NP_SIMPLE_IMPL
228 num
->fval
+=(double)c
/divisor
;
233 tmp
=npnum_mulbase_add(num
, base
, c
);
240 #ifndef NP_SIMPLE_IMPL
252 #ifdef NP_SIMPLE_IMPL
253 num
->type
=NPNUM_FLOAT
;
267 #ifndef NP_SIMPLE_IMPL
268 num
->type
=(num
->exponent
==0 ? NPNUM_INT
: NPNUM_FLOAT
);