1 /*
2  *  Copyright (C) 2000,2014 B. Parisse, Institut Fourier, 38402 St Martin d'Heres
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #undef max
18 #undef min
19 //#define GIAC_VECTOR
20 
21 #ifndef _GIAC_FIRST_H_
22 #define _GIAC_FIRST_H_
23 
24 #ifdef NUMWORKS
25 #define KHICAS 1
26 #endif
27 
28 #ifndef GIAC_VERSION
29 #define GIAC_VERSION VERSION
30 #endif
31 //#include <stdint.h>
32 
33 #ifdef __x86_64__
34 #define x86_64 1
35 #endif
36 
37 // Thanks to Jason Papadopoulos, author of msieve
38 #ifdef BESTA_OS
39 #include <time.h>
40 #define PREFETCH(addr) /* nothing */
41 #elif (defined(__GNUC__) && __GNUC__ >= 3) || defined(__clang__)
42 	#define PREFETCH(addr) __builtin_prefetch(addr)
43 #elif defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(MS_SMART)
44 	#define PREFETCH(addr) PreFetchCacheLine(PF_TEMPORAL_LEVEL_1, addr)
45 #else
46 	#define PREFETCH(addr) /* nothing */
47 #endif
48 
49 #ifdef PNACL
50 #define EMCC
51 #undef HAVE_LIBPTHREAD
52 #undef HAVE_PTHREAD_H
53 #undef x86_64
54 #undef SMARTPTR64
55 #undef HAVE_LONG_DOUBLE
56 #endif
57 
58 #ifdef RTOS_THREADX
59 #define NO_STDEXCEPT 1
60 #endif
61 
62 #define MAX_INTSTACK 32768 // maximal size for allocating an array by int tab[]
63 
64 #ifdef FXCG
65 #define RAND_MAX 2147483647
66 #define clock() 0
67 #define CLOCK() 0
68 #define CLOCK_T int
69 #undef HAVE_LIBDL
70 #undef HAVE_LIBPTHREAD
71 struct Bidon {
72   int i;
iBidon73 Bidon(int i_=0):i(i_){}
flushBidon74   flush(){}
75 };
76 template<class T> Bidon operator << (Bidon ,const T&){ return Bidon(); }
77 inline Bidon operator << (Bidon,const char *){return Bidon();}
78 // #define CIN 0 //std::cin
79 #define COUT Bidon(0) //std::cout
80 #define CERR Bidon(0) //std::cout
81 typedef unsigned pid_t;
82 double lgamma(double);
83 #else // FXCG
84 
85 #ifdef NSPIRE
86 #define clock() 0
87 #undef HAVE_LIBDL
88 #undef HAVE_LIBPTHREAD
89 #include <os.h>
90 #define CIN (*std::console_cin_ptr)
91 #define COUT (*std::console_cin_ptr)
92 #define CERR (*std::console_cin_ptr)
93 #else // NSPIRE
94 #define CIN std::cin
95 #define COUT std::cout
96 #ifdef EMCC
97 #define CERR std::cout
98 extern "C" double emcctime();
99 extern "C" int glinit(int,int,int,int,int);
100 extern "C" void glcontext(int);
101 #define CLOCK emcctime
102 #define CLOCK_T clock_t
103 #else // EMCC
104 #define CERR std::cerr
105 #if defined(MS_SMART) || defined(NO_CLOCK)
106 #define CLOCK() 0
107 #define CLOCK_T int
108 #else
109 #define CLOCK clock
110 #define CLOCK_T clock_t
111 #endif // MS_SMART
112 #endif // EMCC
113 #endif // NSPIRE
114 #endif // FXCG
115 
116 #ifdef __sparc__
117 #define DOUBLEVAL
118 #define GIAC_NO_OPTIMIZATIONS
119 #endif
120 
121 #if defined(BUILDING_NODE_EXTENSION) && defined(_WIN64)
122 #define DOUBLEVAL
123 #endif
124 
125 #ifndef DOUBLEVAL
126 // #define IMMEDIATE_VECTOR 12 // 48 extra bytes = 6 gens or 4 monomials or 3 sparse
127 #define IMMEDIATE_VECTOR 6 // 24 extra bytes = 3 gens or 2 monomials or 1 sparse
128 #endif
129 #define GIAC_MPZ_INIT_SIZE 128 // initial number of bits for mpz
130 
131 #if 0 // def HAVE_LONG_DOUBLE
132 typedef long double giac_double;
133 #else
134 typedef double giac_double;
135 #endif
136 
137 typedef long double  long_double;
138 
139 // sprintf replacement
140 int my_sprintf(char * s, const char * format, ...);
141 #ifdef GIAC_HAS_STO_38
142 //#define WITH_MYOSTREAM
143 #endif
144 
145 #ifdef WITH_MYOSTREAM
146 #include "myostream.h"
147 #else
148 #if defined KHICAS //&& defined STATIC_BUILTIN_LEXER_FUNCTION
149 #include "stdstream"
150 #define my_ostream stdostream
151 #else
152 #define my_ostream std::ostream
153 #endif
154 #endif
155 
156 #ifdef x86_64
157 #define alias_type ulonglong
158 #else
159 #define alias_type size_t
160 #endif
161 
162 #if defined(RTOS_THREADX) || defined(BESTA_OS) || defined NSPIRE
163 #define NO_TEMPLATE_MULTGCD
164 #endif
165 
166 #ifdef BESTA_OS
167 #undef CLOCK
168 #undef CLOCK_T
169 #define CLOCK() PrimeGetNow()
170 #define CLOCK_T int
171 #endif
172 
173 #if !defined HAVE_ALLOCA_H && !defined GIAC_HAS_STO_38 && !defined KHICAS
174 #define alloca _alloca
175 #endif
176 
177 #ifdef NO_UNARY_FUNCTION_COMPOSE
178 
179 #define define_unary_function_eval(name,ptr,name_s) const alias_unary_function_eval name={name_s,0,taylor,0,0,0,ptr,0}
180 #define define_unary_function_eval2(name,ptr,name_s,printptr) const alias_unary_function_eval name={name_s,0,taylor,printptr,0,0,ptr,0}
181 #define define_unary_function_eval3(name,ptr,derivee,name_s) const alias_unary_function_eval name={name_s,derivee,taylor,0,0,0,ptr,0}
182 #define define_unary_function_eval4(name,ptr,name_s,printptr,texprintptr) const alias_unary_function_eval name={name_s,0,taylor,printptr,texprintptr,0,ptr,0}
183 #define define_unary_function_eval5(name,ptr,derive,name_s,printptr,texprintptr) const alias_unary_function_eval name={name_s,derive,taylor,printptr,texprintptr,0,ptr,0}
184 #define define_unary_function_eval_taylor(name,ptr,derive,taylors,name_s) const alias_unary_function_eval name={name_s,derive,taylors,0,0,0,ptr,0}
185 #define define_unary_function_eval_taylor2(name,ptr,derive,taylors,name_s,printptr,texprintptr) const alias_unary_function_eval name={name_s,derive,taylors,printptr,texprintptr,0,ptr,0}
186 #define define_unary_function_eval_quoted(name,ptr,name_s) const alias_unary_function_eval name={name_s,0,taylor,0,0,0,ptr,1}
187 #define define_unary_function_eval2_quoted(name,ptr,name_s,printptr) const alias_unary_function_eval name={name_s,0,taylor,printptr,0,0,ptr,1}
188 #define define_unary_function_eval3_quoted(name,ptr,derivee,name_s) const alias_unary_function_eval name={name_s,derivee,taylor,0,0,0,ptr,1}
189 #define define_unary_function_eval4_quoted(name,ptr,name_s,printptr,texprintptr) const alias_unary_function_eval name={name_s,0,taylor,printptr,texprintptr,0,ptr,1}
190 #define define_unary_function_eval5_quoted(name,ptr,derive,name_s,printptr,texprintptr) const alias_unary_function_eval name={name_s,derive,taylor,printptr,texprintptr,0,ptr,1}
191 #define define_unary_function_eval_taylor_quoted(name,ptr,derive,taylors,name_s) const alias_unary_function_eval name={name_s,derive,taylors,0,0,0,ptr,1}
192 #define define_unary_function_eval_taylor2_quoted(name,ptr,derive,taylors,name_s,printptr,texprintptr) const alias_unary_function_eval name={name_s,derive,taylors,printptr,texprintptr,0,ptr,1}
193 
194 #define define_unary_function_eval_index(u,name,ptr,name_s) const alias_unary_function_eval name={name_s,0,taylor,0,0,0,ptr,u}
195 #define define_unary_function_eval2_index(u,name,ptr,name_s,printptr) const alias_unary_function_eval name={name_s,0,taylor,printptr,0,0,ptr,u}
196 #define define_unary_function_eval3_index(u,name,ptr,derivee,name_s) const alias_unary_function_eval name={name_s,derivee,taylor,0,0,0,ptr,u}
197 #define define_unary_function_eval4_index(u,name,ptr,name_s,printptr,texprintptr) const alias_unary_function_eval name={name_s,0,taylor,printptr,texprintptr,0,ptr,u}
198 #define define_unary_function_eval5_index(u,name,ptr,derive,name_s,printptr,texprintptr) const alias_unary_function_eval name={name_s,derive,taylor,printptr,texprintptr,0,ptr,u}
199 #define define_unary_function_eval_taylor_index(u,name,ptr,derive,taylors,name_s) const alias_unary_function_eval name={name_s,derive,taylors,0,0,0,ptr,u}
200 #define define_unary_function_eval_taylor2_index(u,name,ptr,derive,taylors,name_s,printptr,texprintptr) const alias_unary_function_eval name={name_s,derive,taylors,printptr,texprintptr,0,ptr,u}
201 
202 #define define_partial_derivative_onearg_unary_function_ptr(name,fcn) const size_t name=(const size_t) &fcn
203 #define define_partial_derivative_onearg_genop(name,name_s,genop) const alias_unary_function_eval name##unary_function_eval={name_s,0,taylor,0,0,0,genop,0}; const size_t name##unary_function_ptr = (const size_t)(&name##unary_function_eval); const size_t name=(const size_t) &name##unary_function_ptr
204 
205 #else //  NO_UNARY_FUNCTION_COMPOSE
206 
207 #define define_unary_function_eval(name,ptr,name_s) const unary_function_eval name(0,ptr,name_s)
208 #define define_unary_function_eval2(name,ptr,name_s,printptr) const unary_function_eval name(0,ptr,name_s,printptr)
209 #define define_unary_function_eval3(name,ptr,derivee,name_s) const unary_function_eval name(0,ptr,derivee,name_s)
210 #define define_unary_function_eval4(name,ptr,name_s,printptr,texprintptr) const unary_function_eval name(0,ptr,name_s,printptr,texprintptr)
211 #define define_unary_function_eval5(name,ptr,derive,name_s,printptr,texprintptr) const unary_function_eval name(0,ptr,derive,name_s,printptr,texprintptr)
212 #define define_unary_function_eval_taylor(name,ptr,derive,taylors,name_s) const unary_function_eval name(0,ptr,derive,taylors,name_s)
213 #define define_unary_function_eval_taylor2(name,ptr,derive,taylors,name_s,printptr,texprintptr) const unary_function_eval name(0,ptr,derive,taylors,name_s,printptr,texprintptr)
214 #define define_unary_function_eval_quoted(name,ptr,name_s) const unary_function_eval name(1,ptr,name_s)
215 #define define_unary_function_eval2_quoted(name,ptr,name_s,printptr) const unary_function_eval name(1,ptr,name_s,printptr)
216 #define define_unary_function_eval3_quoted(name,ptr,derivee,name_s) const unary_function_eval name(1,ptr,derivee,name_s)
217 #define define_unary_function_eval4_quoted(name,ptr,name_s,printptr,texprintptr) const unary_function_eval name(1,ptr,name_s,printptr,texprintptr)
218 #define define_unary_function_eval5_quoted(name,ptr,derive,name_s,printptr,texprintptr) const unary_function_eval name(1,ptr,derive,name_s,printptr,texprintptr)
219 #define define_unary_function_eval_taylor_quoted(name,ptr,derive,taylors,name_s) const unary_function_eval name(1,ptr,derive,taylors,name_s)
220 #define define_unary_function_eval_taylor2_quoted(name,ptr,derive,taylors,name_s,printptr,texprintptr) const unary_function_eval name(1,ptr,derive,taylors,name_s,printptr,texprintptr)
221 #define define_unary_function_eval_index(u,name,ptr,name_s) const unary_function_eval name(u,ptr,name_s)
222 #define define_unary_function_eval2_index(u,name,ptr,name_s,printptr) const unary_function_eval name(u,ptr,name_s,printptr)
223 #define define_unary_function_eval3_index(u,name,ptr,derivee,name_s) const unary_function_eval name(u,ptr,derivee,name_s)
224 #define define_unary_function_eval4_index(u,name,ptr,name_s,printptr,texprintptr) const unary_function_eval name(u,ptr,name_s,printptr,texprintptr)
225 #define define_unary_function_eval5_index(u,name,ptr,derive,name_s,printptr,texprintptr) const unary_function_eval name(u,ptr,derive,name_s,printptr,texprintptr)
226 #define define_unary_function_eval_taylor_index(u,name,ptr,derive,taylors,name_s) const unary_function_eval name(u,ptr,derive,taylors,name_s)
227 #define define_unary_function_eval_taylor2_index(u,name,ptr,derive,taylors,name_s,printptr,texprintptr) const unary_function_eval name(u,ptr,derive,taylors,name_s,printptr,texprintptr)
228 
229 #define define_partial_derivative_onearg_genop(name,name_s,genop) static const unary_function_eval name##unary_function_eval(0,genop,name_s); static const unary_function_ptr name##unary_function_ptr(&name##unary_function_eval,0,0); static const partial_derivative_onearg name##partial_derivative_onearg(name##unary_function_ptr); const partial_derivative_onearg * name = &name##partial_derivative_onearg
230 
231 #endif //  NO_UNARY_FUNCTION_COMPOSE
232 
233 #ifdef x86_64
234 #define define_unary_function_ptr(name,alias_name,ptr) const ulonglong alias_name = (ulonglong)(ptr); const unary_function_ptr * const name = (const unary_function_ptr *) &alias_name
235 #else
236 #define define_unary_function_ptr(name,alias_name,ptr) const size_t alias_name = (size_t)(ptr); const unary_function_ptr * const name = (const unary_function_ptr *) &alias_name
237 #endif
238 
239 #ifdef DOUBLEVAL
240 #undef STATIC_BUILTIN_LEXER_FUNCTIONS
241 // otherwise change the definition of charptr_gen in input_lexer.ll
242 #endif
243 
244 #ifdef STATIC_BUILTIN_LEXER_FUNCTIONS
245 #ifdef x86_64
246 #define define_unary_function_ptr5(name,alias_name,ptr,quoted,token) const ulonglong alias_name = ulonglong(ptr); const unary_function_ptr * const name = (const unary_function_ptr *) &alias_name;
247 #else
248 #define define_unary_function_ptr5(name,alias_name,ptr,quoted,token) const size_t alias_name = (size_t)(ptr); const unary_function_ptr * const name = (const unary_function_ptr *) &alias_name;
249 #endif
250 #else
251 #ifdef x86_64
252 #define define_unary_function_ptr5(name,alias_name,ptr,quoted,token) static const unary_function_ptr alias_name##_(ptr,quoted,token); const ulonglong alias_name=(ulonglong)ptr; const unary_function_ptr * const name = &alias_name##_;
253 #else
254 #define define_unary_function_ptr5(name,alias_name,ptr,quoted,token) static const unary_function_ptr alias_name##_(ptr,quoted,token); const size_t alias_name=(size_t)ptr; const unary_function_ptr * const name = &alias_name##_;
255 #endif
256 #endif
257 
258 #ifdef GIAC_HAS_STO_38
259 #ifndef GIAC_GENERIC_CONSTANTS
260 #define GIAC_GENERIC_CONSTANTS
261 #endif
262 #endif
263 
264 #ifdef __VISUALC__
265 #define GIAC_GENERIC_CONSTANTS
266 // Visual C++ is compiling
267 #define VISUALC
268 typedef long pid_t;
269 typedef __int64 longlong ;
270 typedef unsigned __int64 ulonglong ;
271 #ifndef M_PI
272 #define M_PI       3.14159265358979323846
273 #endif
274 #define YY_NO_UNISTD_H
275 #ifndef _SECURE_SCL
276 #define _SECURE_SCL 0
277 #endif
278 #ifndef _CRT_SECURE_NO_WARNINGS
279 #define _CRT_SECURE_NO_WARNINGS
280 #endif
281 #ifndef _CRT_NONSTDC_NO_DEPRECATE
282 #define _CRT_NONSTDC_NO_DEPRECATE 1
283 #endif
284 #else // __VISUALC__
285 typedef long long longlong;
286 typedef unsigned long long ulonglong;
287 #ifdef x86_64
288 typedef int int128_t __attribute__((mode(TI)));
289 typedef unsigned int uint128_t __attribute__((mode(TI)));
290 #ifndef INT128
291 #define INT128 1
292 #endif
293 #endif // x86_64
294 
295 // do not define PSEUDO_MOD if a negative unsigned longlong >> 63 is != 0xffffffffffffffff
296 // #define PSEUDO_MOD accelerates cyclic* gbasis computation significantly
297 // from int_multilinear_combination in vecteur.cc (from rref?)
298 #ifdef FIR
299 #if !(defined(BESTA_OS) || defined(WINDOWS) || defined(OSXIOS) || defined(FIR_LINUX) || defined(FIR_ANDROID) || defined(FREERTOS) || defined(PRIMEWEBASM))
300 // was #if !(defined(IOS) || defined(__ANDROID__)) && !defined(OSX) && !defined(LINUX)
301 #define PSEUDO_MOD
302 #endif
303 #else
304 #define PSEUDO_MOD
305 #endif
306 
307 #endif // __VISUALC__
308 
309 
310 #ifdef VISUALC
swap_giac_double(double & a,double & b)311 inline void swap_giac_double(double & a,double & b){ double c=a; a=b; b=c; }
312 #else
313 #define swap_giac_double(a,b) std::swap<giac_double>(a,b)
314 #endif
315 
316 #if defined WIN32 && defined x86_64
317 typedef longlong ref_count_t;
318 #else
319 typedef int ref_count_t;
320 #endif
321 
322 #ifdef WINSTORE
323 //tw  **NOTE** this is pulled out of winnt.h!!! I don't know why it is not found there.
324 //             there is some sort of interaction in windows ARM builds...
325 //#define CP15_TPIDRURW          15, 0, 13,  0, 2         // Software Thread ID Register, User Read/Write
326 #endif
327 
328 #ifndef SIZEOF_VOID_P
329 #ifdef __APPLE__
330 #ifdef __LP64__
331 #define SIZEOF_VOID_P 8
332 #else
333 #define SIZEOF_VOID_P 4
334 #endif
335 #endif //__APPLE__
336 
337 #ifndef SIZEOF_VOID_P
338 //#error "No SIZEOF_VOID_P defined on this system!!!!"
339 #endif
340 #endif
341 
342 #if __BYTE_ORDER__ ==__ORDER_LITTLE_ENDIAN__ && SIZEOF_VOID_P==8 //(defined(__LP64__) || defined(_WIN64) || (defined(x86_64) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__))
343 #if !defined(BUILDING_NODE_EXTENSION) || !defined(_WIN64)
344 #define SMARTPTR64
345 #endif
346 #else // x86_64
347 #ifdef SMARTPTR64
348 #undef SMARTPTR64
349 #endif // SMARTPTR64
350 #ifdef _I386_
351 #undef _I386_
352 #endif // _I386_
353 #endif // x86_64
354 
355 #ifdef USE_GMP_REPLACEMENTS
356 //#define GIAC_TYPE_ON_8BITS
357 #undef HAVE_GMPXX_H
358 #undef HAVE_LIBMPFR
359 #include "gmp_replacements.h"
360 #else
361 #include <cstddef>
362 #include "gmp.h"
363 #endif // USE_GMP_REPLACEMENTS
364 
365 #ifndef FXCG
366 #include <cassert>
367 #endif
368 
369 class init_gmp_memory
370 {
371 	static int refcount;
372 	public:
373 	init_gmp_memory();
374 	~init_gmp_memory();
375 };
376 extern init_gmp_memory init_gmp_memory_instance;
377 
378 #ifdef BCD
379 // #define ASPEN_GEOMETRY // required also here because of name resolution in identificateur.cc
380 // #define CAS38_DISABLED
381 
382 #include <stdlib.h>
383 #include "bcd_float.h"
384 // abstract structure for BCD float operations
385 // bcd_float.h should define a type for bcd_float,
386 // that fits into a gen (it can be a 64 bits integer but only 56 bits avail.)
387 // For accuracy, the BCD floats should have an expanded form
388 // of type accurate_bcd_float, that one can get using
389 //   accurate_bcd_float * fExpand(bcd_float,accurate_bcd_float *)
390 // This accurate value is returned from a gen g using
391 //   gentobcd(g,accurate_bcd_float *)
392 // bcd_float.h should define the following operations
393 //   fradd_g, frsub_g, fmul_g, fdiv_g, fchs_g, fpow_g
394 //   fLT_g, fGT_g (strict comparison, return bool), fEQ_g,
395 //   fabs_g, fsqrt_g, fZero_g (is ==0)
396 //   bcd_zero, bcd_set_double, bcd_get_double, bcd_set_int, bcd_get_int,
397 struct giac_bcdfloat {
398   bcd_float f;
giac_bcdfloatgiac_bcdfloat399   giac_bcdfloat(const bcd_float & _f){f=_f;}
giac_bcdfloatgiac_bcdfloat400   giac_bcdfloat(int i) {f=bcd_set_int(i);}
giac_bcdfloatgiac_bcdfloat401   giac_bcdfloat(mpz_t * m) {f=bcd_set_mpz(m);}
giac_bcdfloatgiac_bcdfloat402   giac_bcdfloat(const giac_bcdfloat & _f) {f=_f.f;}
giac_bcdfloatgiac_bcdfloat403   giac_bcdfloat(){f=bcd_zero;}
giac_bcdfloatgiac_bcdfloat404   giac_bcdfloat(double d){ f=bcd_set_double(d);}
405 };
406 typedef giac_bcdfloat giac_float;
print_float(const giac_bcdfloat & f,char * ch,CHPPrintData const & pd)407 inline void print_float(const giac_bcdfloat & f,char * ch, CHPPrintData const &pd) { bcd_print(f.f,ch, pd); }
408 void print_float(const giac_bcdfloat & f,char * ch);
409 
410 inline giac_bcdfloat operator + (const giac_bcdfloat & f1,const giac_bcdfloat & f2){
411   return fradd_g(f1.f,f2.f);
412 }
413 inline giac_bcdfloat operator += (giac_bcdfloat & f1,const giac_bcdfloat & f2){
414   f1.f=fradd_g(f1.f,f2.f);
415   return f1;
416 }
417 inline giac_bcdfloat operator - (const giac_bcdfloat & f1,const giac_bcdfloat & f2){
418   return frsub_g(f1.f,f2.f);
419 }
420 inline giac_bcdfloat operator -= (giac_bcdfloat & f1,const giac_bcdfloat & f2){
421   f1.f=frsub_g(f1.f,f2.f);
422   return f1;
423 }
424 inline giac_bcdfloat operator - (const giac_bcdfloat & f1){
425   return fchs_g(f1.f);
426 }
427 inline giac_bcdfloat operator * (const giac_bcdfloat & f1,const giac_bcdfloat & f2){
428   return fmul_g(f1.f,f2.f);
429 }
430 inline giac_bcdfloat operator *= (giac_bcdfloat & f1,const giac_bcdfloat & f2){
431   f1.f=fmul_g(f1.f,f2.f);
432   return f1;
433 }
434 inline giac_bcdfloat operator / (const giac_bcdfloat & f1,const giac_bcdfloat & f2){
435   return fdiv_g(f1.f,f2.f);
436 }
437 inline giac_bcdfloat operator /= (giac_bcdfloat & f1,const giac_bcdfloat & f2){
438   f1.f=fdiv_g(f1.f,f2.f);
439   return f1;
440 }
441 inline bool operator == (const giac_bcdfloat & f1,const giac_bcdfloat & f2){
442   return fEQ_g(f1.f,f2.f);
443 }
444 inline bool operator > (const giac_bcdfloat & f1,const giac_bcdfloat & f2){ return fGT_g(f1.f,f2.f); }
445 inline bool operator < (const giac_bcdfloat & f1,const giac_bcdfloat & f2){ return fLT_g(f1.f,f2.f); }
446 inline bool operator >= (const giac_bcdfloat & f1,const giac_bcdfloat & f2){ return fGE_g(f1.f,f2.f); }
447 inline bool operator <= (const giac_bcdfloat & f1,const giac_bcdfloat & f2){ return fLE_g(f1.f,f2.f); }
get_int(const giac_bcdfloat & f)448 inline int get_int(const giac_bcdfloat & f) { return bcd_get_int(f.f);}
fabs(const giac_bcdfloat & f1)449 inline giac_bcdfloat fabs (const giac_bcdfloat & f1){ return fabs_g(f1.f);}
fsign(const giac_bcdfloat & f1)450 inline int fsign (const giac_bcdfloat & f1){ return fZero_g(f1.f)?0:(fPos_g(f1.f)?1:-1); }
fsqrt(const giac_bcdfloat & f1)451 inline giac_bcdfloat fsqrt (const giac_bcdfloat & f1){ return fsqrt_g(f1.f); }
finv(const giac_bcdfloat & f1)452 inline giac_bcdfloat finv (const giac_bcdfloat & f1){ return finv_g(f1.f); }
fsquare(const giac_bcdfloat & f1)453 inline giac_bcdfloat fsquare (const giac_bcdfloat & f1){ return fsquare_g(f1.f); }
fpow(const giac_bcdfloat & f1,const giac_bcdfloat & f2)454 inline giac_bcdfloat fpow(const giac_bcdfloat & f1,const giac_bcdfloat & f2) {   return fpow_g(f1.f,f2.f); }
fround(const giac_bcdfloat & f1,int digits)455 inline giac_bcdfloat fround(const giac_bcdfloat & f1,int digits) {   if (digits>=0) return frnd_g(f1.f,digits,false); else return frnd_g(f1.f,-digits,true); }
ftrunc(const giac_bcdfloat & f1,int digits)456 inline giac_bcdfloat ftrunc(const giac_bcdfloat & f1,int digits) {   return ftrunc_g(f1.f,digits,false); }
ffloor(const giac_bcdfloat & f)457 inline giac_bcdfloat ffloor(const giac_bcdfloat & f){ return ffloor_g(f.f);}
fceil(const giac_bcdfloat & f)458 inline giac_bcdfloat fceil(const giac_bcdfloat & f){ return fceil_g(f.f);}
fsin(const giac_bcdfloat & f,int angle_mode)459 inline giac_bcdfloat fsin(const giac_bcdfloat & f,int angle_mode){ return fsin_g(f.f,TAngleMode(angle_mode));}
fcos(const giac_bcdfloat & f,int angle_mode)460 inline giac_bcdfloat fcos(const giac_bcdfloat & f,int angle_mode){ return fcos_g(f.f,TAngleMode(angle_mode));}
ftan(const giac_bcdfloat & f,int angle_mode)461 inline giac_bcdfloat ftan(const giac_bcdfloat & f,int angle_mode){ return ftan_g(f.f,TAngleMode(angle_mode));}
fcot(const giac_bcdfloat & f,int angle_mode)462 inline giac_bcdfloat fcot(const giac_bcdfloat & f,int angle_mode){ return fcot_g(f.f,TAngleMode(angle_mode));}
fasin(const giac_bcdfloat & f,int angle_mode)463 inline giac_bcdfloat fasin(const giac_bcdfloat & f,int angle_mode){ return fasin_g(f.f,TAngleMode(angle_mode));}
facos(const giac_bcdfloat & f,int angle_mode)464 inline giac_bcdfloat facos(const giac_bcdfloat & f,int angle_mode){ return facos_g(f.f,TAngleMode(angle_mode));}
fatan(const giac_bcdfloat & f,int angle_mode)465 inline giac_bcdfloat fatan(const giac_bcdfloat & f,int angle_mode){ return fatan_g(f.f,TAngleMode(angle_mode));}
facot(const giac_bcdfloat & f,int angle_mode)466 inline giac_bcdfloat facot(const giac_bcdfloat & f,int angle_mode){ return facot_g(f.f,TAngleMode(angle_mode));}
fsinh(const giac_bcdfloat & f)467 inline giac_bcdfloat fsinh(const giac_bcdfloat & f){ return fsinh_g(f.f);}
fcosh(const giac_bcdfloat & f)468 inline giac_bcdfloat fcosh(const giac_bcdfloat & f){ return fcosh_g(f.f);}
ftanh(const giac_bcdfloat & f)469 inline giac_bcdfloat ftanh(const giac_bcdfloat & f){ return ftanh_g(f.f);}
fasinh(const giac_bcdfloat & f)470 inline giac_bcdfloat fasinh(const giac_bcdfloat & f){ return fasinh_g(f.f);}
facosh(const giac_bcdfloat & f)471 inline giac_bcdfloat facosh(const giac_bcdfloat & f){ return facosh_g(f.f);}
fatanh(const giac_bcdfloat & f)472 inline giac_bcdfloat fatanh(const giac_bcdfloat & f){ return fatanh_g(f.f);}
flog(const giac_bcdfloat & f)473 inline giac_bcdfloat flog(const giac_bcdfloat & f){ return fln_g(f.f);}
fln(const giac_bcdfloat & f)474 inline giac_bcdfloat fln(const giac_bcdfloat & f){ return fln_g(f.f);}
flnp1(const giac_bcdfloat & f)475 inline giac_bcdfloat flnp1(const giac_bcdfloat & f){ return flnp1_g(f.f);}
fexp(const giac_bcdfloat & f)476 inline giac_bcdfloat fexp(const giac_bcdfloat & f){ return fexp_g(f.f);}
fexpm(const giac_bcdfloat & f)477 inline giac_bcdfloat fexpm(const giac_bcdfloat & f){ return fexpm_g(f.f);}
flog10(const giac_bcdfloat & f)478 inline giac_bcdfloat flog10(const giac_bcdfloat & f){ return flog_g(f.f);}
falog10(const giac_bcdfloat & f)479 inline giac_bcdfloat falog10(const giac_bcdfloat & f){ return falog_g(f.f);}
fgamma(const giac_bcdfloat & f)480 inline giac_bcdfloat fgamma(const giac_bcdfloat & f){ return fgamma_g(f.f); }
fmod(const giac_bcdfloat & f1,const giac_bcdfloat & f2)481 inline giac_bcdfloat fmod(const giac_bcdfloat & f1,const giac_bcdfloat & f2){ return fmod_g(f1.f,f2.f);}
fnthroot(const giac_bcdfloat & f1,const giac_bcdfloat & f2)482 inline giac_bcdfloat fnthroot(const giac_bcdfloat & f1,const giac_bcdfloat & f2){ return fnthroot_g(f1.f,f2.f);}
fmax(const giac_bcdfloat & f1,const giac_bcdfloat & f2)483 inline giac_bcdfloat fmax(const giac_bcdfloat & f1,const giac_bcdfloat & f2){ return fmax_g(f1.f,f2.f);}
fmin(const giac_bcdfloat & f1,const giac_bcdfloat & f2)484 inline giac_bcdfloat fmin(const giac_bcdfloat & f1,const giac_bcdfloat & f2){ return fmin_g(f1.f,f2.f);}
fis_exactly_zero(const giac_bcdfloat & f)485 inline bool fis_exactly_zero(const giac_bcdfloat & f){ return fZero_g(f.f);}
fis_integer(const giac_bcdfloat & f)486 inline bool fis_integer(const giac_bcdfloat & f){ return fInteger_g(f.f); }
fis_positive(const giac_bcdfloat & f)487 inline bool fis_positive(const giac_bcdfloat & f){ return fPos_g(f.f);}
fis_nan(const giac_bcdfloat & f)488 inline bool fis_nan(const giac_bcdfloat & f){ return fNaN_g(f.f); }
fis_inf(const giac_bcdfloat & f)489 inline bool fis_inf(const giac_bcdfloat & f){ return finfmax_g(f.f); }
fis_inf_notmax(const giac_bcdfloat & f)490 inline bool fis_inf_notmax(const giac_bcdfloat & f){ return fInf_g(f.f); }
fpi()491 inline giac_bcdfloat fpi(){ return fpi_g(); }
492 inline giac_bcdfloat atan2f(const giac_bcdfloat & re,const giac_bcdfloat & im,int anglemode=0){ return fatan2_g(re.f,im.f,anglemode); }
493 
strtobcd(const char * nptr,const char ** endptr,CHPPrintData const & pd)494 inline giac_bcdfloat strtobcd(const char *nptr,const char **endptr, CHPPrintData const &pd){ return fstrtobcd(nptr,endptr,pd); }
495 giac_bcdfloat strtobcd(const char *nptr,const char **endptr);
get_double(const giac_bcdfloat & f)496 inline double get_double(const giac_bcdfloat & f) {
497   // FIXME
498 #ifdef GIAC_HAS_STO_38
499   return bcd_get_float(f.f);
500 #else
501   char ch[32]; char * endchar;
502   bool pos=fis_positive(f) || fis_exactly_zero(f);
503   if (fis_inf(f)){ double d=0.0; return 1./d; }
504   if (fis_nan(f)){ double d=0.0; return 0./d; }
505   if (!pos) ch[0]='-';
506   print_float(pos?f.f:(-f).f,pos?ch:ch+1,'.'|('E'<<16)|(' '<<24),12+(15<<8),0);
507   return strtod(ch,&endchar);
508 #endif
509 }
510 #else // defined BCD
511 
512 #include <cmath>
513 typedef float giac_float;
514 #define fis_inf_notmax fis_inf
fis_exactly_zero(float f)515 inline bool fis_exactly_zero(float f){ return f==0;}
get_double(float f)516 inline double get_double(float f) { return f;}
get_int(float f)517 inline int get_int(float f) { return int(f);}
fsign(float f1)518 inline int fsign (float f1){return f1==0?0:(f1>0?1:-1);}
519 float fsqrt (float f1);
520 void print_float(const giac_float & f,char * ch);
fpow(float f1,float f2)521 inline float fpow(float f1,float f2){
522 #ifdef NSPIRE
523   return pow(f1,f2);
524 #else
525   return std::pow(f1,f2);
526 #endif
527 }
ffloor(float f1)528 inline float ffloor(float f1){
529 #ifdef NSPIRE
530   return floor(f1);
531 #else
532   return std::floor(f1);
533 #endif
534 }
finv(float f1)535 inline float finv(float f1){ return 1/f1; }
536 #if defined __APPLE__ || defined EMCC || defined NO_BSD
fgamma(float f1)537 inline float fgamma(float f1){ return tgammaf(f1); }
538 #else
539 #if defined(__MINGW_H) || defined(VISUALC) || defined(FXCG)// FIXME gamma, not used
fgamma(float f1)540 inline float fgamma(float f1){ return f1; }
541 #else
fgamma(float f1)542 inline float fgamma(float f1){ return gammaf(f1); } // or tgammaf(f1) on some versions of emscripten
543 #endif
544 #endif
545 #ifdef FXCG
atan2f(float f1,float f2,int rad)546 inline float atan2f(float f1,float f2,int rad){ if (rad) return std::atan2(f1,f2); else return std::atan2(f1,f2)*180/3.14159265358979323846;}
547 #else
atan2f(float f1,float f2,int rad)548 inline float atan2f(float f1,float f2,int rad){ if (rad) return atan2f(f1,f2); else return atan2f(f1,f2)*180/M_PI;}
549 #endif
550 #define fis_nan my_isnan
551 #define fis_inf my_isinf
552 #endif // BCD
553 
554 #ifdef FIR_ANDROID
555 #undef B0 //this conflicts with a define
556 #undef bcopy //this conflicts with a define
557 #endif
558 #endif // _GIAC_FIRST_H_
559