1 /*
2  * This file is part of MPSolve 3.2.1
3  *
4  * Copyright (C) 2001-2020, Dipartimento di Matematica "L. Tonelli", Pisa.
5  * License: http://www.gnu.org/licenses/gpl.html GPL version 3 or higher
6  *
7  * Authors:
8  *   Dario Andrea Bini <bini@dm.unipi.it>
9  *   Giuseppe Fiorentino <fiorent@dm.unipi.it>
10  *   Leonardo Robol <leonardo.robol@unipi.it>
11  */
12 
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <math.h>
17 #include <float.h>
18 #include <limits.h>
19 #include <mps/mt.h>
20 #include <mps/mps.h>
21 
22 /***********************************************************
23 **              machine dependent constants               **
24 ***********************************************************/
25 
26 #define NBT           DBL_MANT_DIG
27 
28 /***********************************************************
29 **              input/output formats                      **
30 ***********************************************************/
31 
32 #define FMTE           "% 18.14e"
33 #define FMTF           "% 16.14f"
34 #define CPLX_OUT_UFMT  FMTE " " FMTE
35 #define CPLX_OUT_FMT   "(" FMTE ", " FMTE ")"
36 #define CPLX_INP_UFMT  "%le %le"
37 #define CPLX_INP_FMT   "(%le, %le)"
38 #define RDPE_OUT_UFMT  FMTF "e%+04li"
39 #define RDPE_OUT_FMT   FMTF "x%+04li"
40 #define RDPE_INP_UFMT  "%lf e %ld"
41 #define RDPE_INP_FMT   "%lf x %ld"
42 #define CDPE_OUT_UFMT  RDPE_OUT_UFMT " " RDPE_OUT_UFMT
43 #define CDPE_OUT_FMT   "(" RDPE_OUT_FMT ", " RDPE_OUT_FMT ")"
44 #define CDPE_INP_UFMT  RDPE_INP_UFMT " " RDPE_INP_UFMT
45 #define CDPE_INP_FMT   "(" RDPE_INP_FMT ", " RDPE_INP_FMT ")"
46 #define DEF_STR_SIZE   80
47 
48 /***********************************************************
49 **              numerical constants                       **
50 ***********************************************************/
51 
52 #define LOG10_2      0.30102999566398119521
53 #define LOG2_10      3.32192809488736234787
54 #define LOG_2        0.69314718055994530941
55 #define LOG_10       2.30258509299404568401
56 
57 /***********************************************************
58 **              functions for cplx_t                      **
59 ***********************************************************/
60 
61 #ifdef MPS_USE_BUILTIN_COMPLEX
62 
63 /* base constants */
64 const cplx_t cplx_zero = { { 0.0, 0.0 } };
65 const cplx_t cplx_one = { { 1.0, 0.0 } };
66 const cplx_t cplx_i = { { 0.0, 1.0 } };
67 
68 void
cplx_d(cplx_t temp_cplx,double r,double i)69 cplx_d (cplx_t temp_cplx, double r, double i)
70 /* return (r, i) */
71 {
72   cplx_Re (temp_cplx) = r;
73   cplx_Im (temp_cplx) = i;
74 }
75 
76 void
cplx_clear(cplx_t x)77 cplx_clear (cplx_t x)
78 /* x = 0 + I 0 */
79 {
80   cplx_Move (x, cplx_zero);
81 }
82 
83 void
cplx_set(cplx_t rx,const cplx_t x)84 cplx_set (cplx_t rx, const cplx_t x)
85 /* rx = x */
86 {
87   cplx_Move (rx, x);
88 }
89 
90 void
cplx_set_d(cplx_t x,double dr,double di)91 cplx_set_d (cplx_t x, double dr, double di)
92 /* x = dr + I di */
93 {
94   cplx_Re (x) = dr;
95   cplx_Im (x) = di;
96 }
97 
98 int
cplx_set_str(cplx_t x,const char * s)99 cplx_set_str (cplx_t x, const char *s)
100 /* set from string as (re , im) */
101 {
102   return sscanf (s, CPLX_INP_FMT, &cplx_Re (x), &cplx_Im (x)) == 2;
103 }
104 
105 void
cplx_get_d(double * dr,double * di,const cplx_t x)106 cplx_get_d (double *dr, double *di, const cplx_t x)
107 /* *dr = re(x), *di = im(x) */
108 {
109   *dr = cplx_Re (x);
110   *di = cplx_Im (x);
111 }
112 
113 char *
cplx_get_str(char * s,const cplx_t x)114 cplx_get_str (char *s, const cplx_t x)
115 /* output to string as (re , im) */
116 {
117   if (s == NULL && (s = (char*)mps_malloc (DEF_STR_SIZE)) == NULL)
118     return NULL;
119   sprintf (s, CPLX_OUT_FMT, cplx_Re (x), cplx_Im (x));
120   return s;
121 }
122 
123 void
cplx_neg(cplx_t rx,const cplx_t x)124 cplx_neg (cplx_t rx, const cplx_t x)
125 /* rx = -x */
126 {
127   cplx_Re (rx) = -cplx_Re (x);
128   cplx_Im (rx) = -cplx_Im (x);
129 }
130 
131 void
cplx_con(cplx_t rx,const cplx_t x)132 cplx_con (cplx_t rx, const cplx_t x)
133 /* rx = conj(x) */
134 {
135   cplx_Re (rx) = cplx_Re (x);
136   cplx_Im (rx) = -cplx_Im (x);
137 }
138 
139 double
cplx_smod(const cplx_t x)140 cplx_smod (const cplx_t x)
141 /* returns |x|^2 */
142 {
143   return cplx_Re (x) * cplx_Re (x) + cplx_Im (x) * cplx_Im (x);
144 }
145 
146 double
cplx_mod(const cplx_t x)147 cplx_mod (const cplx_t x)
148 /* returns |x| */
149 {
150   double d;
151 
152   if (fabs (cplx_Re (x)) > fabs (cplx_Im (x)))
153     {
154       d = cplx_Im (x) / cplx_Re (x);
155       return fabs (cplx_Re (x)) * sqrt (1.0 + d * d);
156     }
157   else if (cplx_Im (x) == 0.0)
158     return 0.0;
159   d = cplx_Re (x) / cplx_Im (x);
160   return fabs (cplx_Im (x)) * sqrt (1.0 + d * d);
161 }
162 
163 void
cplx_inv(cplx_t rx,const cplx_t x)164 cplx_inv (cplx_t rx, const cplx_t x)
165 /* rx = 1 / x */
166 {
167   double d1, d2;
168 
169   if (fabs (cplx_Re (x)) > fabs (cplx_Im (x)))
170     {
171       d1 = cplx_Im (x) / cplx_Re (x);
172       d2 = 1.0 / (cplx_Re (x) * (1.0 + d1 * d1));
173       cplx_Re (rx) = d2;
174       cplx_Im (rx) = -d2 * d1;
175     }
176   else
177     {
178       d1 = cplx_Re (x) / cplx_Im (x);
179       d2 = 1.0 / (cplx_Im (x) * (1.0 + d1 * d1));
180       cplx_Im (rx) = -d2;
181       cplx_Re (rx) = d2 * d1;
182     }
183 }
184 
185 void
cplx_sqr(cplx_t rx,const cplx_t x)186 cplx_sqr (cplx_t rx, const cplx_t x)
187 /* rx = x * x */
188 {
189   double d;                     /* necessary when rx=x1 or rx=x2 */
190 
191   d = cplx_Re (x) * cplx_Re (x) - cplx_Im (x) * cplx_Im (x);
192   cplx_Im (rx) = 2.0 * cplx_Re (x) * cplx_Im (x);
193   cplx_Re (rx) = d;
194 }
195 
196 void
cplx_rot(cplx_t rx,const cplx_t x)197 cplx_rot (cplx_t rx, const cplx_t x)
198 /* rx = I x */
199 {
200   double t;
201 
202   t = cplx_Re (x);
203   cplx_Re (rx) = -cplx_Im (x);
204   cplx_Im (rx) = t;
205 }
206 
207 void
cplx_flip(cplx_t rx,const cplx_t x)208 cplx_flip (cplx_t rx, const cplx_t x)
209 /* rx = (Im(x), Re(x)) */
210 {
211   double t;
212 
213   t = cplx_Re (x);
214   cplx_Re (rx) = cplx_Im (x);
215   cplx_Im (rx) = t;
216 }
217 
218 /**
219  * @brief Add the complex number <code>x1</code> and <code>x2</code> and
220  * store the result in <code>rx</code>
221  *
222  * @param rx The place where the result will be stored.
223  * @param x1 The left operand of the addition.
224  * @param x2 The right operand of the addition.
225  */
226 void
cplx_add(cplx_t rx,const cplx_t x1,const cplx_t x2)227 cplx_add (cplx_t rx, const cplx_t x1, const cplx_t x2)
228 /* rx = x1 + x2 */
229 {
230   cplx_Re (rx) = cplx_Re (x1) + cplx_Re (x2);
231   cplx_Im (rx) = cplx_Im (x1) + cplx_Im (x2);
232 }
233 
234 /**
235  * @brief Substract from <code>x1</code> the value
236  * stored in <code>x2</code> and store the result
237  * in <code>rx</code>.
238  *
239  * @param rx The place where the result will be stored.
240  * @param x1 The left operand of the subtraction.
241  * @param x2 The right operand of the subtraction.
242  */
243 void
cplx_sub(cplx_t rx,const cplx_t x1,const cplx_t x2)244 cplx_sub (cplx_t rx, const cplx_t x1, const cplx_t x2)
245 /* rx = x1 - x2 */
246 {
247   cplx_Re (rx) = cplx_Re (x1) - cplx_Re (x2);
248   cplx_Im (rx) = cplx_Im (x1) - cplx_Im (x2);
249 }
250 
251 /**
252  * @brief Multiply the value stored in <code>x1</code>
253  * and in <code>x2</code> and store the result in
254  * <code>rx</code>.
255  *
256  * @param rx The place where the result wil be stored.
257  * @param x1 The left operand of the multiplication.
258  * @param x2 The right operando of the multiplication.
259  */
260 void
cplx_mul(cplx_t rx,const cplx_t x1,const cplx_t x2)261 cplx_mul (cplx_t rx, const cplx_t x1, const cplx_t x2)
262 /* rx = x1 * x2 */
263 {
264   double d;                     /* necessary when rx=x1 or rx=x2 */
265 
266   d = cplx_Re (x1) * cplx_Re (x2) - cplx_Im (x1) * cplx_Im (x2);
267   cplx_Im (rx) = cplx_Im (x1) * cplx_Re (x2) + cplx_Re (x1) * cplx_Im (x2);
268   cplx_Re (rx) = d;
269 }
270 
271 void
cplx_mul_d(cplx_t rx,const cplx_t x,double d)272 cplx_mul_d (cplx_t rx, const cplx_t x, double d)
273 /* rx = x * d */
274 {
275   cplx_Re (rx) = cplx_Re (x) * d;
276   cplx_Im (rx) = cplx_Im (x) * d;
277 }
278 
279 /**
280  * @brief Divide the complex value in <code>x1</code> by the
281  * value in <code>x2</code> and store the results in <code>rx</code>.
282  *
283  * @param rx The place where the result will be stored.
284  * @param x1 The left operand of the division.
285  * @param x2 The right operando of the division.
286  */
287 void
cplx_div(cplx_t rx,const cplx_t x1,const cplx_t x2)288 cplx_div (cplx_t rx, const cplx_t x1, const cplx_t x2)
289 /* rx = x1 / x2 */
290 {
291   cplx_t ctmp;
292 
293   cplx_inv (ctmp, x2);
294   cplx_mul (rx, x1, ctmp);
295 }
296 
297 void
cplx_div_d(cplx_t rx,const cplx_t x,double d)298 cplx_div_d (cplx_t rx, const cplx_t x, double d)
299 /* rx = x / d */
300 {
301   cplx_Re (rx) = cplx_Re (x) / d;
302   cplx_Im (rx) = cplx_Im (x) / d;
303 }
304 
305 void
cplx_pow_si(cplx_t rx,const cplx_t x,register signed long int i)306 cplx_pow_si (cplx_t rx, const cplx_t x, register signed long int i)
307 /* rx = x ^ i , i integer */
308 {
309   cplx_t t;
310 
311   cplx_Move (t, x);
312   cplx_Move (rx, cplx_one);
313 
314   if (i < 0)
315     {
316       cplx_inv_eq (t);
317       i = -i;
318     }
319   while (i)
320     {
321       if (i & 1)
322         cplx_mul_eq (rx, t);
323       cplx_sqr_eq (t);
324       i >>= 1;                  /* divide i by 2 */
325     }
326 }
327 
328 void
cplx_swap(cplx_t x1,cplx_t x2)329 cplx_swap (cplx_t x1, cplx_t x2)
330 /* x1 <-> x2 */
331 {
332   cplx_t t;
333 
334   cplx_Move (t, x1);
335   cplx_Move (x1, x2);
336   cplx_Move (x2, t);
337 }
338 
339 void
cplx_neg_eq(cplx_t x)340 cplx_neg_eq (cplx_t x)
341 /* x = -x */
342 {
343   cplx_Re (x) = -cplx_Re (x);
344   cplx_Im (x) = -cplx_Im (x);
345 }
346 
347 void
cplx_con_eq(cplx_t x)348 cplx_con_eq (cplx_t x)
349 /* x = conj(x) */
350 {
351   cplx_Im (x) = -cplx_Im (x);
352 }
353 
354 void
cplx_inv_eq(cplx_t x)355 cplx_inv_eq (cplx_t x)
356 /* rx = 1 / x */
357 {
358   double d1, d2;
359 
360   if (fabs (cplx_Re (x)) > fabs (cplx_Im (x)))
361     {
362       d1 = cplx_Im (x) / cplx_Re (x);
363       if (DBL_MAX / (1.0 + d1 * d1) < fabs (cplx_Re (x)))       /*#G 27/4/98 */
364         d2 = 0.0;               /*#G 27/4/98 */
365       else                      /*#G 27/4/98 */
366         d2 = 1.0 / (cplx_Re (x) * (1.0 + d1 * d1));
367       cplx_Re (x) = d2;
368       cplx_Im (x) = -d2 * d1;
369     }
370   else
371     {
372       d1 = cplx_Re (x) / cplx_Im (x);
373       if (DBL_MAX / (1.0 + d1 * d1) < fabs (cplx_Re (x)))       /*#G 27/4/98 */
374         d2 = 0.0;               /*#G 27/4/98 */
375       else                      /*#G 27/4/98 */
376         d2 = 1.0 / (cplx_Im (x) * (1.0 + d1 * d1));
377       cplx_Im (x) = -d2;
378       cplx_Re (x) = d2 * d1;
379     }
380 }
381 
382 void
cplx_sqr_eq(cplx_t x)383 cplx_sqr_eq (cplx_t x)
384 /* x = x * x */
385 {
386   double d;
387 
388   d = cplx_Re (x) * cplx_Re (x) - cplx_Im (x) * cplx_Im (x);
389   cplx_Im (x) *= 2.0 * cplx_Re (x);
390   cplx_Re (x) = d;
391 }
392 
393 void
cplx_rot_eq(cplx_t x)394 cplx_rot_eq (cplx_t x)
395 /* x = I x */
396 {
397   double d;
398 
399   d = cplx_Re (x);
400   cplx_Re (x) = -cplx_Im (x);
401   cplx_Im (x) = d;
402 }
403 
404 void
cplx_flip_eq(cplx_t x)405 cplx_flip_eq (cplx_t x)
406 /* x = (Im(x), Re(x)) */
407 {
408   double d;
409 
410   d = cplx_Re (x);
411   cplx_Re (x) = cplx_Im (x);
412   cplx_Im (x) = d;
413 }
414 
415 void
cplx_add_eq(cplx_t rx,const cplx_t x)416 cplx_add_eq (cplx_t rx, const cplx_t x)
417 /* rx = rx + x */
418 {
419   cplx_Re (rx) += cplx_Re (x);
420   cplx_Im (rx) += cplx_Im (x);
421 }
422 
423 void
cplx_sub_eq(cplx_t rx,const cplx_t x)424 cplx_sub_eq (cplx_t rx, const cplx_t x)
425 /* rx = rx - x */
426 {
427   cplx_Re (rx) -= cplx_Re (x);
428   cplx_Im (rx) -= cplx_Im (x);
429 }
430 
431 void
cplx_mul_eq(cplx_t rx,const cplx_t x)432 cplx_mul_eq (cplx_t rx, const cplx_t x)
433 /* rx = rx * x */
434 {
435   double d;
436 
437   d = cplx_Re (rx) * cplx_Re (x) - cplx_Im (rx) * cplx_Im (x);
438   cplx_Im (rx) = cplx_Im (rx) * cplx_Re (x) + cplx_Re (rx) * cplx_Im (x);
439   cplx_Re (rx) = d;
440 }
441 
442 void
cplx_mul_eq_d(cplx_t x,double d)443 cplx_mul_eq_d (cplx_t x, double d)
444 /* x = x * d */
445 {
446   cplx_Re (x) *= d;
447   cplx_Im (x) *= d;
448 }
449 
450 void
cplx_div_eq(cplx_t rx,const cplx_t x)451 cplx_div_eq (cplx_t rx, const cplx_t x)
452 /* rx = x1 / x2 */
453 {
454   cplx_t ctmp;
455 
456   cplx_inv (ctmp, x);
457   cplx_mul_eq (rx, ctmp);
458 }
459 
460 void
cplx_div_eq_d(cplx_t x,double d)461 cplx_div_eq_d (cplx_t x, double d)
462 /* x = x / d */
463 {
464   cplx_Re (x) /= d;
465   cplx_Im (x) /= d;
466 }
467 
468 void
cplx_pow_eq_si(cplx_t x,register signed long int i)469 cplx_pow_eq_si (cplx_t x, register signed long int i)
470 /* x = x ^ i , i integer */
471 {
472   cplx_t t;
473 
474   cplx_Move (t, x);
475   cplx_Move (x, cplx_one);
476 
477   if (i < 0)
478     {
479       cplx_inv_eq (t);
480       i = -i;
481     }
482   while (i)
483     {
484       if (i & 1)
485         cplx_mul_eq (x, t);
486       cplx_sqr_eq (t);
487       i >>= 1;                  /* divide i by 2 */
488     }
489 }
490 
491 /*------------  relational ops.  -------------------------*/
492 
493 int
cplx_eq_zero(const cplx_t x)494 cplx_eq_zero (const cplx_t x)
495 /* x == 0 */
496 {
497   return cplx_Re (x) == 0.0 && cplx_Im (x) == 0.0;
498 }
499 
500 int
cplx_eq(const cplx_t x1,const cplx_t x2)501 cplx_eq (const cplx_t x1, const cplx_t x2)
502 /* x1 == x2 */
503 {
504   return cplx_Re (x1) == cplx_Re (x2) && cplx_Im (x1) == cplx_Im (x2);
505 }
506 
507 int
cplx_ne(const cplx_t x1,const cplx_t x2)508 cplx_ne (const cplx_t x1, const cplx_t x2)
509 /* x1 != x2 */
510 {
511   return cplx_Re (x1) != cplx_Re (x2) || cplx_Im (x1) != cplx_Im (x2);
512 }
513 
514 /*------------  vector functions  ------------------------*/
515 
516 void
cplx_vinit(cplx_t v[],long size)517 cplx_vinit (cplx_t v[], long size)
518 {
519   long i;
520 
521   for (i = 0; i < size; i++)
522     cplx_Move (v[i], cplx_zero);
523 }
524 
525 #else
526 
527 const cplx_t cplx_zero = { 0.0 };
528 const cplx_t cplx_one = { 1.0 };
529 const cplx_t cplx_i = { 1.0I };
530 
531 #endif
532 
533 int
cplx_check_fpe(cplx_t c)534 cplx_check_fpe (cplx_t c)
535 /* Check if the components are NaN or Inf */
536 {
537   int fp = 0;
538 
539   if (isnan (cplx_Re (c)))
540     fp += 1;
541   if (isnan (cplx_Im (c)))
542     fp += (1 << 1);
543   if (isinf (cplx_Re (c)))
544     fp += (1 << 2);
545   if (isinf (cplx_Im (c)))
546     fp += (1 << 3);
547   return fp;
548 }
549 
550 /*------------  I/O functions  ---------------------------*/
551 
552 int
cplx_out_str_u(FILE * f,const cplx_t x)553 cplx_out_str_u (FILE * f, const cplx_t x)
554 /* output to file as re im */
555 {
556   if (f == NULL)
557     f = stdout;
558   return fprintf (f, CPLX_OUT_UFMT, cplx_Re (x), cplx_Im (x));
559 }
560 
561 int
cplx_out_str(FILE * f,const cplx_t x)562 cplx_out_str (FILE * f, const cplx_t x)
563 /* output to file as (re, im) */
564 {
565   if (f == NULL)
566     f = stdout;
567   return fprintf (f, CPLX_OUT_FMT, cplx_Re (x), cplx_Im (x));
568 }
569 
570 int
cplx_inp_str_u(cplx_t x,FILE * f)571 cplx_inp_str_u (cplx_t x, FILE * f)
572 /* input from file as (re, im) */
573 {
574   double real, imag;
575 
576   if (f == NULL)
577     f = stdin;
578   int ret = fscanf (f, CPLX_INP_UFMT, &real, &imag);
579   cplx_set_d (x, real, imag);
580   return ret;
581 }
582 
583 int
cplx_inp_str(cplx_t x,FILE * f)584 cplx_inp_str (cplx_t x, FILE * f)
585 /* input from file as (re, im) */
586 {
587   double real, imag;
588 
589   if (f == NULL)
590     f = stdin;
591   int ret = fscanf (f, CPLX_INP_FMT, &real, &imag);
592   cplx_set_d (x, real, imag);
593   return ret;
594 }
595 
596 /***********************************************************
597 **              functions for rdpe_t                      **
598 ***********************************************************/
599 
600 /* normalize: mant(e) in [1/2, 1) */
601 #define rdpe_Norm(E) \
602   { \
603     int i; \
604     rdpe_Mnt (E) = frexp (rdpe_Mnt (E), &i); \
605     if (rdpe_Mnt (E) == 0.0) rdpe_Esp (E) = 0L; \
606     else rdpe_Esp (E) += i; \
607   }
608 
609 /* constants */
610 const rdpe_t rdpe_zero = { { 0.0, 0L } };
611 const rdpe_t rdpe_one = { { 0.5, 1L } };
612 const rdpe_t RDPE_MAX = { { 0.5, LONG_MAX } };
613 const rdpe_t RDPE_MIN = { { 0.5, LONG_MIN } };
614 const rdpe_t rdpe_maxd = { { 0.5, DBL_MAX_EXP } };
615 const rdpe_t rdpe_mind = { { 0.5, DBL_MIN_EXP } };
616 const rdpe_t RDPE_BIG = { { 0.5, LONG_MAX >> 10 } };
617 
618 void
rdpe_d(rdpe_t temp_rdpe,double d)619 rdpe_d (rdpe_t temp_rdpe, double d)
620 /* return d as a rdpe_t */
621 {
622   rdpe_Mnt (temp_rdpe) = d;
623   rdpe_Esp (temp_rdpe) = 0L;
624   rdpe_Norm (temp_rdpe);
625 }
626 
627 void
rdpe_2dl(rdpe_t temp_rdpe,double d,long l)628 rdpe_2dl (rdpe_t temp_rdpe, double d, long l)
629 /* return d*2^l as a rdpe_t */
630 {
631   rdpe_Mnt (temp_rdpe) = d;
632   rdpe_Esp (temp_rdpe) = l;
633   rdpe_Norm (temp_rdpe);;
634 }
635 
636 void
rdpe_clear(rdpe_t e)637 rdpe_clear (rdpe_t e)
638 /* e = 0 */
639 {
640   rdpe_Move (e, rdpe_zero);
641 }
642 
643 void
rdpe_set(rdpe_t re,const rdpe_t e)644 rdpe_set (rdpe_t re, const rdpe_t e)
645 /* re = e */
646 {
647   rdpe_Move (re, e);
648 }
649 
650 void
rdpe_set_dl(rdpe_t e,double d,long int l)651 rdpe_set_dl (rdpe_t e, double d, long int l)
652 /* e = d*10^l */
653 {
654   double x;
655 
656   if (d == 0.0)
657     {
658       rdpe_Move (e, rdpe_zero);
659       return;
660     }
661   else if (d > 0.0)
662     {
663       rdpe_Mnt (e) = log (d) / LOG_2 + l * LOG2_10;
664       rdpe_Mnt (e) = pow (2.0, modf (rdpe_Mnt (e), &x));
665     }
666   else
667     {                           /* d < 0 */
668       rdpe_Mnt (e) = log (-d) / LOG_2 + l * LOG2_10;
669       rdpe_Mnt (e) = -pow (2.0, modf (rdpe_Mnt (e), &x));
670     }
671   rdpe_Esp (e) = (long int)x;
672   rdpe_Norm (e);
673 }
674 
675 void
rdpe_set_2dl(rdpe_t e,double d,long int l)676 rdpe_set_2dl (rdpe_t e, double d, long int l)
677 /* e = d*2^l */
678 {
679   rdpe_Mnt (e) = d;
680   rdpe_Esp (e) = l;
681   rdpe_Norm (e);
682 }
683 
684 void
rdpe_set_d(rdpe_t e,double d)685 rdpe_set_d (rdpe_t e, double d)
686 /* e = d  */
687 {
688   rdpe_Mnt (e) = d;
689   rdpe_Esp (e) = 0L;
690   rdpe_Norm (e);
691 }
692 
693 int
rdpe_set_str(rdpe_t e,const char * s)694 rdpe_set_str (rdpe_t e, const char *s)
695 /* input from string as mant x exp) */
696 {
697   if (sscanf (s, RDPE_INP_FMT, &rdpe_Mnt (e), &rdpe_Esp (e)) != 2)
698     return 0;
699   rdpe_set_dl (e, rdpe_Mnt (e), rdpe_Esp (e));
700   return 1;
701 }
702 
703 void
rdpe_get_dl(double * d,long int * l,const rdpe_t e)704 rdpe_get_dl (double *d, long int *l, const rdpe_t e)
705 /* returns mantissa and exponent of e */
706 {
707   double x;
708 
709   if (rdpe_Mnt (e) == 0.0)
710     {
711       *d = 0.0;
712       *l = 0L;
713     }
714   else if (rdpe_Mnt (e) > 0)
715     {
716       *d = log10 (rdpe_Mnt (e)) + rdpe_Esp (e) * LOG10_2;
717       *d = pow (10.0, modf (*d, &x));
718       *l = (long int)x;
719     }
720   else
721     {                           /* rdpe_Mnt(e) > 0 */
722       *d = log10 (-rdpe_Mnt (e)) + rdpe_Esp (e) * LOG10_2;
723       *d = -pow (10.0, modf (*d, &x));
724       *l = (long int)x;
725     }
726 }
727 
728 void
rdpe_get_2dl(double * d,long int * l,const rdpe_t e)729 rdpe_get_2dl (double *d, long int *l, const rdpe_t e)
730 /* returns mantissa and exponent of e in base 2 */
731 {
732   *d = rdpe_Mnt (e);
733   *l = rdpe_Esp (e);
734 }
735 
736 double
rdpe_get_d(const rdpe_t e)737 rdpe_get_d (const rdpe_t e)
738 {
739   return ldexp (rdpe_Mnt (e), (int)rdpe_Esp (e));
740 }
741 
742 char *
rdpe_get_str(char * s,const rdpe_t e)743 rdpe_get_str (char *s, const rdpe_t e)
744 /* output to string */
745 {
746   double d;
747   long int l;
748 
749   if (s == NULL && (s = (char*)mps_malloc (DEF_STR_SIZE)) == NULL)
750     return NULL;
751   rdpe_get_dl (&d, &l, e);
752   sprintf (s, RDPE_OUT_FMT, d, l);
753   return s;
754 }
755 
756 void
rdpe_neg(rdpe_t re,const rdpe_t e)757 rdpe_neg (rdpe_t re, const rdpe_t e)
758 /* re = -e */
759 {
760   rdpe_Mnt (re) = -rdpe_Mnt (e);
761   rdpe_Esp (re) = rdpe_Esp (e);
762 }
763 
764 void
rdpe_abs(rdpe_t re,const rdpe_t e)765 rdpe_abs (rdpe_t re, const rdpe_t e)
766 /* re = |e| */
767 {
768   rdpe_Mnt (re) = (rdpe_Mnt (e) > 0) ? rdpe_Mnt (e) : -rdpe_Mnt (e);
769   rdpe_Esp (re) = rdpe_Esp (e);
770 }
771 
772 void
rdpe_inv(rdpe_t re,const rdpe_t e)773 rdpe_inv (rdpe_t re, const rdpe_t e)
774 /* re = 1 / e */
775 {
776   rdpe_Mnt (re) = 1.0 / rdpe_Mnt (e);
777   rdpe_Esp (re) = -rdpe_Esp (e);
778   rdpe_Norm (re);
779 }
780 
781 void
rdpe_sqr(rdpe_t re,const rdpe_t e)782 rdpe_sqr (rdpe_t re, const rdpe_t e)
783 /* re = e * e */
784 {
785   rdpe_Mnt (re) = rdpe_Mnt (e) * rdpe_Mnt (e);
786   rdpe_Esp (re) = rdpe_Esp (e) + rdpe_Esp (e);
787   rdpe_Norm (re);
788 }
789 
790 void
rdpe_sqrt(rdpe_t re,const rdpe_t e)791 rdpe_sqrt (rdpe_t re, const rdpe_t e)
792 /* re = e^(1/2) */
793 {
794   if (rdpe_Esp (e) & 1)
795     {
796       rdpe_Mnt (re) = sqrt (rdpe_Mnt (e) / 2.0);
797       rdpe_Esp (re) = (rdpe_Esp (e) + 1) / 2;
798     }
799   else
800     {
801       rdpe_Mnt (re) = sqrt (rdpe_Mnt (e));
802       rdpe_Esp (re) = rdpe_Esp (e) / 2;
803     }
804   rdpe_Norm (re);
805 }
806 
807 double
rdpe_log(const rdpe_t e)808 rdpe_log (const rdpe_t e)
809 /* returns log(e) */
810 {
811   return log (rdpe_Mnt (e)) + rdpe_Esp (e) * LOG_2;
812 }
813 
814 double
rdpe_log10(const rdpe_t e)815 rdpe_log10 (const rdpe_t e)
816 /* returns log10(e) */
817 {
818   return (log (rdpe_Mnt (e)) + rdpe_Esp (e) * LOG_2) / LOG_10;
819 }
820 
821 void
rdpe_exp(rdpe_t re,const rdpe_t e)822 rdpe_exp (rdpe_t re, const rdpe_t e)
823 /* re = E^(e) */
824 {
825   long int i;
826 
827   i = rdpe_Esp (e);
828   rdpe_set_2dl (re, exp (rdpe_Mnt (e)), 0L);
829 
830   if (i >= 0)
831     while (i > 0)
832       {
833         rdpe_sqr_eq (re);
834         i--;
835       }
836   else
837     while (i < 0)
838       {
839         rdpe_sqrt_eq (re);
840         i++;
841       }
842 }
843 
844 void
rdpe_mul(rdpe_t re,const rdpe_t e1,const rdpe_t e2)845 rdpe_mul (rdpe_t re, const rdpe_t e1, const rdpe_t e2)
846 /* re = e1 * e2 */
847 {
848   if (rdpe_Esp (e1) >= 0 && (rdpe_Esp (e2) >= LONG_MAX - rdpe_Esp (e1)))
849     {
850       rdpe_set (re, RDPE_MAX);
851       return;
852     }
853   if (rdpe_Esp (e1) <= 0 && (rdpe_Esp (e2) <= LONG_MIN - rdpe_Esp (e1)))
854     {
855       rdpe_set (re, RDPE_MAX);
856       return;
857     }
858   rdpe_Mnt (re) = rdpe_Mnt (e1) * rdpe_Mnt (e2);
859   rdpe_Esp (re) = rdpe_Esp (e1) + rdpe_Esp (e2);
860   rdpe_Norm (re);
861 }
862 
863 void
rdpe_mul_d(rdpe_t re,const rdpe_t e,double d)864 rdpe_mul_d (rdpe_t re, const rdpe_t e, double d)
865 /* re = e * d */
866 {
867   int esp;
868 
869   frexp (d, &esp);
870   if (rdpe_Esp (e) >= 0 && (esp >= LONG_MAX - rdpe_Esp (e)))
871     {
872       rdpe_set (re, RDPE_MAX);
873       return;
874     }
875   if (rdpe_Esp (e) <= 0 && (esp <= LONG_MIN - rdpe_Esp (e)))
876     {
877       rdpe_set (re, RDPE_MAX);
878       return;
879     }
880   rdpe_Mnt (re) = rdpe_Mnt (e) * d;
881   rdpe_Esp (re) = rdpe_Esp (e);
882   rdpe_Norm (re);
883 }
884 
885 void
rdpe_mul_2exp(rdpe_t re,const rdpe_t e,unsigned long int i)886 rdpe_mul_2exp (rdpe_t re, const rdpe_t e, unsigned long int i)
887 /* re = e * 2^i */
888 {
889   rdpe_Mnt (re) = rdpe_Mnt (e);
890   rdpe_Esp (re) = rdpe_Esp (e) + i;
891 }
892 
893 void
rdpe_div(rdpe_t re,const rdpe_t e1,const rdpe_t e2)894 rdpe_div (rdpe_t re, const rdpe_t e1, const rdpe_t e2)
895 /* re = e1 / e2 */
896 {
897   rdpe_Mnt (re) = rdpe_Mnt (e1) / rdpe_Mnt (e2);
898   rdpe_Esp (re) = rdpe_Esp (e1) - rdpe_Esp (e2);
899   rdpe_Norm (re);
900 }
901 
902 void
rdpe_div_d(rdpe_t re,const rdpe_t e,double d)903 rdpe_div_d (rdpe_t re, const rdpe_t e, double d)
904 /* re = e / d */
905 {
906   rdpe_Mnt (re) = rdpe_Mnt (e) / d;
907   rdpe_Esp (re) = rdpe_Esp (e);
908   rdpe_Norm (re);
909 }
910 
911 void
rdpe_div_2exp(rdpe_t re,const rdpe_t e,unsigned long int i)912 rdpe_div_2exp (rdpe_t re, const rdpe_t e, unsigned long int i)
913 /* re = e / 2^i */
914 {
915   rdpe_Mnt (re) = rdpe_Mnt (e);
916   rdpe_Esp (re) = rdpe_Esp (e) - i;
917 }
918 
919 void
rdpe_add(rdpe_t re,const rdpe_t e1,const rdpe_t e2)920 rdpe_add (rdpe_t re, const rdpe_t e1, const rdpe_t e2)
921 /* re = e1 + e2 */
922 {
923   long delta;
924 
925   /* Check for overflows */
926   if (rdpe_Mnt (e1) > 0 && rdpe_Mnt (e2) > 0 && rdpe_Esp (e1) == LONG_MAX && rdpe_Esp (e2) == LONG_MAX)
927     {
928       rdpe_set (re, RDPE_MAX);
929       return;
930     }
931   if (rdpe_Mnt (e1) < 0 && rdpe_Mnt (e2) < 0 && rdpe_Esp (e1) == LONG_MAX && rdpe_Esp (e2) == LONG_MAX)
932     {
933       rdpe_set_dl (re, -0.5, LONG_MAX);
934       return;
935     }
936 
937   if (rdpe_Mnt (e2) == 0.0)
938     {
939       rdpe_Move (re, e1);
940       return;
941     }
942   if (rdpe_Mnt (e1) == 0.0)
943     {
944       rdpe_Move (re, e2);
945       return;
946     }
947   delta = rdpe_Esp (e1) - rdpe_Esp (e2);
948 
949   if (delta > NBT)
950     rdpe_Move (re, e1);
951   else if (delta < -NBT)
952     rdpe_Move (re, e2);
953   else if (delta == 0)
954     {
955       rdpe_Mnt (re) = rdpe_Mnt (e1) + rdpe_Mnt (e2);
956       rdpe_Esp (re) = rdpe_Esp (e1);
957       rdpe_Norm (re);
958     }
959   else if (delta > 0)
960     {
961       rdpe_Mnt (re) = rdpe_Mnt (e1) + ldexp (rdpe_Mnt (e2), (int)-delta);
962       rdpe_Esp (re) = rdpe_Esp (e1);
963       rdpe_Norm (re);
964     }
965   else
966     {                           /* delta < 0 */
967       rdpe_Mnt (re) = ldexp (rdpe_Mnt (e1), (int)delta) + rdpe_Mnt (e2);
968       rdpe_Esp (re) = rdpe_Esp (e2);
969       rdpe_Norm (re);
970     }
971 }
972 
973 void
rdpe_sub(rdpe_t re,const rdpe_t e1,const rdpe_t e2)974 rdpe_sub (rdpe_t re, const rdpe_t e1, const rdpe_t e2)
975 /* re = e1 - e2 */
976 {
977   long delta;
978 
979   if (rdpe_Mnt (e2) == 0.0)
980     {
981       rdpe_Move (re, e1);
982       return;
983     }
984   if (rdpe_Mnt (e1) == 0.0)
985     {
986       rdpe_Mnt (re) = -rdpe_Mnt (e2);
987       rdpe_Esp (re) = rdpe_Esp (e2);
988       return;
989     }
990 
991   delta = rdpe_Esp (e1) - rdpe_Esp (e2);
992 
993   if (delta > NBT)
994     rdpe_Move (re, e1);
995   else if (delta < -NBT)
996     {
997       rdpe_Mnt (re) = -rdpe_Mnt (e2);
998       rdpe_Esp (re) = rdpe_Esp (e2);
999     }
1000   else if (delta == 0)
1001     {
1002       rdpe_Mnt (re) = rdpe_Mnt (e1) - rdpe_Mnt (e2);
1003       rdpe_Esp (re) = rdpe_Esp (e1);
1004       rdpe_Norm (re);
1005     }
1006   else if (delta > 0)
1007     {
1008       rdpe_Mnt (re) = rdpe_Mnt (e1) - ldexp (rdpe_Mnt (e2), (int)-delta);
1009       rdpe_Esp (re) = rdpe_Esp (e1);
1010       rdpe_Norm (re);
1011     }
1012   else
1013     {                           /* delta < 0 */
1014       rdpe_Mnt (re) = ldexp (rdpe_Mnt (e1), (int)delta) - rdpe_Mnt (e2);
1015       rdpe_Esp (re) = rdpe_Esp (e2);
1016       rdpe_Norm (re);
1017     }
1018 }
1019 
1020 void
rdpe_add_d(rdpe_t re,const rdpe_t e,double d)1021 rdpe_add_d (rdpe_t re, const rdpe_t e, double d)
1022 /* re = e + d */
1023 {
1024   rdpe_t t;
1025 
1026   rdpe_set_d (t, d);
1027   rdpe_add (re, e, t);
1028 }
1029 
1030 void
rdpe_sub_d(rdpe_t re,const rdpe_t e,double d)1031 rdpe_sub_d (rdpe_t re, const rdpe_t e, double d)
1032 /* re = e - d */
1033 {
1034   rdpe_t t;
1035 
1036   rdpe_set_d (t, d);
1037   rdpe_sub (re, e, t);
1038 }
1039 
1040 void
rdpe_pow_d(rdpe_t re,const rdpe_t e,double d)1041 rdpe_pow_d (rdpe_t re, const rdpe_t e, double d)
1042 /* re = e ^ d */
1043 {
1044   double a, i, f;
1045 
1046   a = d * (log (rdpe_Mnt (e)) / LOG_2 + rdpe_Esp (e));
1047   f = modf (a, &i);
1048   rdpe_set_2dl (re, exp (f * LOG_2), (long)i);
1049 }
1050 
1051 void
rdpe_pow_d2(rdpe_t re,const rdpe_t e,double d)1052 rdpe_pow_d2 (rdpe_t re, const rdpe_t e, double d)
1053 /* re = e ^ d, d double */
1054 {
1055   double a, i;
1056 
1057   a = pow (rdpe_Mnt (e), d);
1058   a *= pow (2.0, modf (rdpe_Esp (e) * d, &i));
1059   rdpe_set_2dl (re, a, (long)i);
1060 }
1061 
1062 void
rdpe_pow_si(rdpe_t re,const rdpe_t e,register signed long int i)1063 rdpe_pow_si (rdpe_t re, const rdpe_t e, register signed long int i)
1064 /* re = e ^ i, i integer */
1065 {
1066   rdpe_t t;
1067 
1068   rdpe_Move (t, e);
1069   rdpe_Move (re, rdpe_one);
1070 
1071   if (i < 0)
1072     {
1073       rdpe_inv (t, t);
1074       i = -i;
1075     }
1076   while (i)
1077     {
1078       if (i & 1)
1079         rdpe_mul_eq (re, t);
1080       rdpe_sqr_eq (t);
1081       i >>= 1;                  /* divide i by 2 */
1082     }
1083 }
1084 
1085 void
rdpe_swap(rdpe_t e1,rdpe_t e2)1086 rdpe_swap (rdpe_t e1, rdpe_t e2)
1087 /* e1 <-> e2 */
1088 {
1089   rdpe_t t;
1090 
1091   rdpe_Move (t, e1);
1092   rdpe_Move (e1, e2);
1093   rdpe_Move (e2, t);
1094 }
1095 
1096 void
rdpe_neg_eq(rdpe_t e)1097 rdpe_neg_eq (rdpe_t e)
1098 /* e = -e */
1099 {
1100   rdpe_Mnt (e) = -rdpe_Mnt (e);
1101   rdpe_Esp (e) = rdpe_Esp (e);
1102 }
1103 
1104 void
rdpe_abs_eq(rdpe_t e)1105 rdpe_abs_eq (rdpe_t e)
1106 /* e = |e| */
1107 {
1108   rdpe_Mnt (e) = (rdpe_Mnt (e) > 0) ? rdpe_Mnt (e) : -rdpe_Mnt (e);
1109 }
1110 
1111 void
rdpe_inv_eq(rdpe_t e)1112 rdpe_inv_eq (rdpe_t e)
1113 /* e = 1 / e */
1114 {
1115   rdpe_Mnt (e) = 1.0 / rdpe_Mnt (e);
1116   rdpe_Esp (e) = -rdpe_Esp (e);
1117   rdpe_Norm (e);
1118 }
1119 
1120 void
rdpe_sqr_eq(rdpe_t e)1121 rdpe_sqr_eq (rdpe_t e)
1122 /* e = e * e */
1123 {
1124   rdpe_Mnt (e) *= rdpe_Mnt (e);
1125   rdpe_Esp (e) <<= 1;           /* multiply by 2 */
1126   rdpe_Norm (e);
1127 }
1128 
1129 void
rdpe_sqrt_eq(rdpe_t e)1130 rdpe_sqrt_eq (rdpe_t e)
1131 /* e = e^(1/2) */
1132 {
1133   if (rdpe_Esp (e) & 1)
1134     {                           /* odd test */
1135       rdpe_Mnt (e) = sqrt (rdpe_Mnt (e) / 2.0);
1136       rdpe_Esp (e) = (rdpe_Esp (e) + 1) / 2;
1137     }
1138   else
1139     {
1140       rdpe_Mnt (e) = sqrt (rdpe_Mnt (e));
1141       rdpe_Esp (e) /= 2;
1142     }
1143   rdpe_Norm (e);
1144 }
1145 
1146 void
rdpe_exp_eq(rdpe_t e)1147 rdpe_exp_eq (rdpe_t e)
1148 /* re = E^(e) */
1149 {
1150   long int i;
1151 
1152   i = rdpe_Esp (e);
1153   rdpe_set_2dl (e, exp (rdpe_Mnt (e)), 0L);
1154 
1155   if (i >= 0)
1156     while (i > 0)
1157       {
1158         rdpe_sqr_eq (e);
1159         i--;
1160       }
1161   else
1162     while (i < 0)
1163       {
1164         rdpe_sqrt_eq (e);
1165         i++;
1166       }
1167 }
1168 
1169 void
rdpe_mul_eq(rdpe_t re,const rdpe_t e)1170 rdpe_mul_eq (rdpe_t re, const rdpe_t e)
1171 /* re = re * e */
1172 {
1173   ;
1174   if (rdpe_Esp (re) >= 0 && (rdpe_Esp (e) >= LONG_MAX - rdpe_Esp (re)))
1175     {
1176       rdpe_set (re, RDPE_MAX);
1177       return;
1178     }
1179   if (rdpe_Esp (re) <= 0 && (rdpe_Esp (e) <= LONG_MIN - rdpe_Esp (re)))
1180     {
1181       rdpe_set (re, RDPE_MAX);
1182       return;
1183     }
1184   rdpe_Mnt (re) *= rdpe_Mnt (e);
1185   rdpe_Esp (re) += rdpe_Esp (e);
1186   rdpe_Norm (re);
1187 }
1188 
1189 void
rdpe_mul_eq_d(rdpe_t e,double d)1190 rdpe_mul_eq_d (rdpe_t e, double d)
1191 /* e = e * d */
1192 {
1193   int esp;
1194 
1195   frexp (d, &esp);
1196   if (rdpe_Esp (e) >= 0 && (esp >= LONG_MAX - rdpe_Esp (e)))
1197     {
1198       rdpe_set (e, RDPE_MAX);
1199       return;
1200     }
1201   if (rdpe_Esp (e) <= 0 && (esp <= LONG_MIN - rdpe_Esp (e)))
1202     {
1203       rdpe_set (e, RDPE_MAX);
1204       return;
1205     }
1206   rdpe_Mnt (e) *= d;
1207   rdpe_Norm (e);
1208 }
1209 
1210 void
rdpe_mul_eq_2exp(rdpe_t e,unsigned long int i)1211 rdpe_mul_eq_2exp (rdpe_t e, unsigned long int i)
1212 /* e = e * 2^i */
1213 {
1214   rdpe_Esp (e) += i;
1215 }
1216 
1217 void
rdpe_div_eq(rdpe_t re,const rdpe_t e)1218 rdpe_div_eq (rdpe_t re, const rdpe_t e)
1219 /* re = re / e */
1220 {
1221   rdpe_Mnt (re) /= rdpe_Mnt (e);
1222   rdpe_Esp (re) -= rdpe_Esp (e);
1223   rdpe_Norm (re);
1224 }
1225 
1226 void
rdpe_div_eq_d(rdpe_t e,double d)1227 rdpe_div_eq_d (rdpe_t e, double d)
1228 /* e = e / d */
1229 {
1230   rdpe_Mnt (e) /= d;
1231   rdpe_Norm (e);
1232 }
1233 
1234 void
rdpe_div_eq_2exp(rdpe_t e,unsigned long int i)1235 rdpe_div_eq_2exp (rdpe_t e, unsigned long int i)
1236 /* e = e / 2^i */
1237 {
1238   rdpe_Esp (e) -= i;
1239 }
1240 
1241 void
rdpe_add_eq(rdpe_t re,const rdpe_t e)1242 rdpe_add_eq (rdpe_t re, const rdpe_t e)
1243 /* re = re + e */
1244 {
1245   long int delta;
1246 
1247   if (rdpe_Mnt (e) == 0.0)
1248     return;
1249   if (rdpe_Mnt (re) == 0.0)
1250     {
1251       rdpe_Move (re, e);
1252       return;
1253     }
1254   delta = rdpe_Esp (re) - rdpe_Esp (e);
1255 
1256   if (delta > NBT)
1257     return;
1258   else if (delta < -NBT)
1259     rdpe_Move (re, e);
1260   else if (delta == 0)
1261     {
1262       rdpe_Mnt (re) += rdpe_Mnt (e);
1263       rdpe_Norm (re);
1264     }
1265   else if (delta > 0)
1266     {
1267       rdpe_Mnt (re) += ldexp (rdpe_Mnt (e), (int)-delta);
1268       rdpe_Norm (re);
1269     }
1270   else
1271     {                           /* delta < 0 */
1272       rdpe_Mnt (re) = ldexp (rdpe_Mnt (re), (int)delta) + rdpe_Mnt (e);
1273       rdpe_Esp (re) = rdpe_Esp (e);
1274       rdpe_Norm (re);
1275     }
1276 }
1277 
1278 void
rdpe_sub_eq(rdpe_t re,const rdpe_t e)1279 rdpe_sub_eq (rdpe_t re, const rdpe_t e)
1280 /* re = re - e */
1281 {
1282   long int delta;
1283 
1284   if (rdpe_Mnt (e) == 0.0)
1285     return;
1286   if (rdpe_Mnt (re) == 0.0)
1287     {
1288       rdpe_Mnt (re) = -rdpe_Mnt (e);
1289       rdpe_Esp (re) = rdpe_Esp (e);
1290       return;
1291     }
1292   delta = rdpe_Esp (re) - rdpe_Esp (e);
1293 
1294   if (delta > NBT)
1295     return;
1296   else if (delta < -NBT)
1297     {
1298       rdpe_Mnt (re) = -rdpe_Mnt (e);
1299       rdpe_Esp (re) = rdpe_Esp (e);
1300     }
1301   else if (delta == 0)
1302     {
1303       rdpe_Mnt (re) -= rdpe_Mnt (e);
1304       rdpe_Norm (re);
1305     }
1306   else if (delta > 0)
1307     {
1308       rdpe_Mnt (re) -= ldexp (rdpe_Mnt (e), (int)-delta);
1309       rdpe_Norm (re);
1310     }
1311   else
1312     {                           /* delta < 0 */
1313       rdpe_Mnt (re) = ldexp (rdpe_Mnt (re), (int)delta) - rdpe_Mnt (e);
1314       rdpe_Esp (re) = rdpe_Esp (e);
1315       rdpe_Norm (re);
1316     }
1317 }
1318 
1319 void
rdpe_add_eq_d(rdpe_t e,double d)1320 rdpe_add_eq_d (rdpe_t e, double d)
1321 /* re = e + d */
1322 {
1323   rdpe_t t;
1324 
1325   rdpe_set_d (t, d);
1326   rdpe_add_eq (e, t);
1327 }
1328 
1329 void
rdpe_sub_eq_d(rdpe_t e,double d)1330 rdpe_sub_eq_d (rdpe_t e, double d)
1331 /* re = e - d */
1332 {
1333   rdpe_t t;
1334 
1335   rdpe_set_d (t, d);
1336   rdpe_sub_eq (e, t);
1337 }
1338 
1339 void
rdpe_pow_eq_d(rdpe_t e,double d)1340 rdpe_pow_eq_d (rdpe_t e, double d)
1341 /* re = e ^ d */
1342 {
1343   double a, i, f;
1344 
1345   a = d * (log (rdpe_Mnt (e)) / LOG_2 + rdpe_Esp (e));
1346   f = modf (a, &i);
1347   rdpe_set_2dl (e, exp (f * LOG_2), (long)i);
1348 }
1349 
1350 void
rdpe_pow_eq_si(rdpe_t e,register signed long int i)1351 rdpe_pow_eq_si (rdpe_t e, register signed long int i)
1352 /* e = e ^ i, i integer */
1353 {
1354   rdpe_t t;
1355 
1356   rdpe_Move (t, e);
1357   rdpe_Move (e, rdpe_one);
1358 
1359   if (i < 0)
1360     {
1361       rdpe_inv (t, t);
1362       i = -i;
1363     }
1364   while (i)
1365     {
1366       if (i & 1)
1367         rdpe_mul_eq (e, t);
1368       rdpe_sqr_eq (t);
1369       i >>= 1;                  /* divide i by 2 */
1370     }
1371 }
1372 
1373 void
rdpe_fac_ui(rdpe_t e,register unsigned long int n)1374 rdpe_fac_ui (rdpe_t e, register unsigned long int n)
1375 /* e = n! */
1376 {
1377   rdpe_Move (e, rdpe_one);
1378   while (n > 1)
1379     {
1380       rdpe_mul_eq_d (e, (double)n);
1381       n--;
1382     }
1383 }
1384 
1385 /*------------  relational ops.  -------------------------*/
1386 
1387 int
rdpe_cmp(const rdpe_t e1,const rdpe_t e2)1388 rdpe_cmp (const rdpe_t e1, const rdpe_t e2)
1389 /* e1 <!> e2 */
1390 {
1391   rdpe_t t;
1392 
1393   rdpe_sub (t, e1, e2);
1394   if (rdpe_Mnt (t) > 0.0)
1395     return 1;
1396   if (rdpe_Mnt (t) < 0.0)
1397     return -1;
1398   return 0;
1399 }
1400 
1401 int
rdpe_sgn(const rdpe_t e)1402 rdpe_sgn (const rdpe_t e)
1403 /* sign(e) */
1404 {
1405   if (rdpe_Mnt (e) > 0.0)
1406     return 1;
1407   if (rdpe_Mnt (e) < 0.0)
1408     return -1;
1409   return 0;
1410 }
1411 
1412 int
rdpe_eq_zero(const rdpe_t e)1413 rdpe_eq_zero (const rdpe_t e)
1414 /* e == 0 */
1415 {
1416   return rdpe_Mnt (e) == 0.0 && rdpe_Esp (e) == 0;
1417 }
1418 
1419 int
rdpe_eq(const rdpe_t e1,const rdpe_t e2)1420 rdpe_eq (const rdpe_t e1, const rdpe_t e2)
1421 /* e1 == e2 */
1422 {
1423   return rdpe_Mnt (e1) == rdpe_Mnt (e2) && rdpe_Esp (e1) == rdpe_Esp (e2);
1424 }
1425 
1426 int
rdpe_ne(const rdpe_t e1,const rdpe_t e2)1427 rdpe_ne (const rdpe_t e1, const rdpe_t e2)
1428 /* e1 != e2 */
1429 {
1430   return rdpe_Mnt (e1) != rdpe_Mnt (e2) || rdpe_Esp (e1) != rdpe_Esp (e2);
1431 }
1432 
1433 int
rdpe_lt(const rdpe_t e1,const rdpe_t e2)1434 rdpe_lt (const rdpe_t e1, const rdpe_t e2)
1435 /* e1 < e2 */
1436 {
1437   rdpe_t t;
1438 
1439   if (rdpe_Mnt (e1) > 0 && rdpe_Mnt (e2) < 0)
1440     return 1;
1441   if (rdpe_Mnt (e1) < 0 && rdpe_Mnt (e1) > 0)
1442     return 0;
1443 
1444   /* This check works only if the numbers are non zero */
1445   if (rdpe_Mnt (e1) != 0 && rdpe_Mnt (e2) != 0)
1446     {
1447       if (rdpe_Esp (e1) > rdpe_Esp (e2))
1448         return 0;
1449       if (rdpe_Esp (e2) > rdpe_Esp (e1))
1450         return 1;
1451     }
1452 
1453   rdpe_sub (t, e1, e2);
1454   return rdpe_Mnt (t) < 0.0;
1455 }
1456 
1457 int
rdpe_le(const rdpe_t e1,const rdpe_t e2)1458 rdpe_le (const rdpe_t e1, const rdpe_t e2)
1459 /* e1 <= e2 */
1460 {
1461   rdpe_t t;
1462 
1463   if (rdpe_Mnt (e1) > 0 && rdpe_Mnt (e2) < 0)
1464     return 1;
1465   if (rdpe_Mnt (e1) < 0 && rdpe_Mnt (e1) > 0)
1466     return 0;
1467 
1468   /* This check works only if the numbers are non zero */
1469   if (rdpe_Mnt (e1) != 0 && rdpe_Mnt (e2) != 0)
1470     {
1471       if (rdpe_Esp (e1) > rdpe_Esp (e2))
1472         return 0;
1473       if (rdpe_Esp (e2) > rdpe_Esp (e1))
1474         return 1;
1475     }
1476 
1477   rdpe_sub (t, e1, e2);
1478   return rdpe_Mnt (t) <= 0.0;
1479 }
1480 
1481 int
rdpe_gt(const rdpe_t e1,const rdpe_t e2)1482 rdpe_gt (const rdpe_t e1, const rdpe_t e2)
1483 /* e1 > e2 */
1484 {
1485   rdpe_t t;
1486 
1487   if (rdpe_Mnt (e1) > 0 && rdpe_Mnt (e2) < 0)
1488     return 0;
1489   if (rdpe_Mnt (e1) < 0 && rdpe_Mnt (e1) > 0)
1490     return 1;
1491 
1492   /* This check works only if both DPE are non zero */
1493   if (rdpe_Mnt (e1) != 0 && rdpe_Mnt (e2) != 0)
1494     {
1495       if (rdpe_Esp (e1) > rdpe_Esp (e2))
1496         return 1;
1497       if (rdpe_Esp (e2) > rdpe_Esp (e1))
1498         return 0;
1499     }
1500 
1501   rdpe_sub (t, e1, e2);
1502   return rdpe_Mnt (t) > 0.0;
1503 }
1504 
1505 int
rdpe_ge(const rdpe_t e1,const rdpe_t e2)1506 rdpe_ge (const rdpe_t e1, const rdpe_t e2)
1507 /* e1 >= e2 */
1508 {
1509   rdpe_t t;
1510 
1511   if (rdpe_Mnt (e1) > 0 && rdpe_Mnt (e2) < 0)
1512     return 0;
1513   if (rdpe_Mnt (e1) < 0 && rdpe_Mnt (e1) > 0)
1514     return 1;
1515 
1516   /* This check works only if both DPE are non zero */
1517   if (rdpe_Mnt (e1) != 0 && rdpe_Mnt (e2) != 0)
1518     {
1519       if (rdpe_Esp (e1) > rdpe_Esp (e2))
1520         return 1;
1521       if (rdpe_Esp (e2) > rdpe_Esp (e1))
1522         return 0;
1523     }
1524 
1525   rdpe_sub (t, e1, e2);
1526   return rdpe_Mnt (t) >= 0.0;
1527 }
1528 
1529 /*------------  I/O functions  ---------------------------*/
1530 
1531 int
rdpe_out_str_u(FILE * f,const rdpe_t e)1532 rdpe_out_str_u (FILE * f, const rdpe_t e)
1533 /* output as mantissa e exponent, base 10 */
1534 {
1535   double d;
1536   long int l;
1537 
1538   if (f == NULL)
1539     f = stdout;
1540   rdpe_get_dl (&d, &l, e);
1541   return fprintf (f, RDPE_OUT_UFMT, d, l);
1542 }
1543 
1544 int
rdpe_out_str(FILE * f,const rdpe_t e)1545 rdpe_out_str (FILE * f, const rdpe_t e)
1546 /* output as mantissa x exponent, base 10 */
1547 {
1548   double d;
1549   long int l;
1550 
1551   if (f == NULL)
1552     f = stdout;
1553   rdpe_get_dl (&d, &l, e);
1554   return fprintf (f, RDPE_OUT_FMT, d, l);
1555 }
1556 
1557 int
rdpe_inp_str_u(rdpe_t e,FILE * f)1558 rdpe_inp_str_u (rdpe_t e, FILE * f)
1559 /* input from file as mant e exp */
1560 {
1561   double d;
1562   long int l;
1563 
1564   if (f == NULL)
1565     f = stdin;
1566   if (fscanf (f, RDPE_INP_UFMT, &d, &l) != 2)
1567     return 0;
1568   rdpe_set_dl (e, d, l);
1569   return 1;
1570 }
1571 
1572 int
rdpe_inp_str(rdpe_t e,FILE * f)1573 rdpe_inp_str (rdpe_t e, FILE * f)
1574 /* input from file as mant x exp */
1575 {
1576   double d;
1577   long int l;
1578 
1579   if (f == NULL)
1580     f = stdin;
1581   if (fscanf (f, RDPE_INP_FMT, &d, &l) != 2)
1582     return 0;
1583   rdpe_set_dl (e, d, l);
1584   return 1;
1585 }
1586 
1587 int
rdpe_inp_str_flex(rdpe_t e,FILE * f)1588 rdpe_inp_str_flex (rdpe_t e, FILE * f)
1589 /* More flexible input for rdpe */
1590 {
1591   double d;
1592   long int l = 0;
1593 
1594   if (f == NULL)
1595     f = stdin;
1596 
1597   if (fscanf (f, RDPE_INP_FMT, &d, &l) < 1)
1598     return 0;
1599   rdpe_set_dl (e, d, l);
1600   return 1;
1601 }
1602 
1603 int
rdpe_inp_sstr_flex(rdpe_t e,char * f)1604 rdpe_inp_sstr_flex (rdpe_t e, char *f)
1605 /* More flexible input for rdpe */
1606 {
1607   double d;
1608   long int l = 0;
1609 
1610   if (sscanf (f, RDPE_INP_FMT, &d, &l) < 1)
1611     return 0;
1612   rdpe_set_dl (e, d, l);
1613   return 1;
1614 }
1615 
1616 /*------------  vector functions  ------------------------*/
1617 
1618 void
rdpe_vinit(rdpe_t v[],long size)1619 rdpe_vinit (rdpe_t v[], long size)
1620 {
1621   long i;
1622 
1623   for (i = 0; i < size; i++)
1624     rdpe_Move (v[i], rdpe_zero);
1625 }
1626 
1627 void
gdpe_add(gdpe_t res,gdpe_t g1,gdpe_t g2)1628 gdpe_add (gdpe_t res, gdpe_t g1, gdpe_t g2)
1629 {
1630   rdpe_add (gdpe_Val (res), gdpe_Val (g1), gdpe_Val (g2));
1631   rdpe_add (gdpe_Eps (res), gdpe_Eps (g1), gdpe_Eps (g2));
1632   gdpe_update_rel_from_abs (res);
1633 }
1634 
1635 void
gdpe_sub(gdpe_t res,gdpe_t g1,gdpe_t g2)1636 gdpe_sub (gdpe_t res, gdpe_t g1, gdpe_t g2)
1637 {
1638   rdpe_sub (gdpe_Val (res), gdpe_Val (g1), gdpe_Val (g2));
1639   rdpe_add (gdpe_Eps (res), gdpe_Eps (g1), gdpe_Eps (g2));
1640   gdpe_update_rel_from_abs (res);
1641 }
1642 
1643 void
gdpe_mul(gdpe_t res,gdpe_t g1,gdpe_t g2)1644 gdpe_mul (gdpe_t res, gdpe_t g1, gdpe_t g2)
1645 {
1646   rdpe_mul (gdpe_Val (res), gdpe_Val (g1), gdpe_Val (g2));
1647   if (gdpe_eq_zero (g1) || gdpe_eq_zero (g2))
1648     {
1649       rdpe_set (gdpe_Eps (res), rdpe_zero);
1650       return;
1651     }
1652 
1653   rdpe_add (gdpe_Rel (res), gdpe_Rel (g1), gdpe_Rel (g2));
1654   gdpe_update_abs_from_rel (res);
1655 }
1656 
1657 void
gdpe_div(gdpe_t res,gdpe_t g1,gdpe_t g2)1658 gdpe_div (gdpe_t res, gdpe_t g1, gdpe_t g2)
1659 {
1660   rdpe_div (gdpe_Val (res), gdpe_Val (g1), gdpe_Val (g2));
1661   if (gdpe_eq_zero (g1))
1662     {
1663       rdpe_set (gdpe_Eps (res), rdpe_zero);
1664       return;
1665     }
1666 
1667   rdpe_add (gdpe_Rel (res), gdpe_Rel (g1), gdpe_Rel (g2));
1668   gdpe_update_abs_from_rel (res);
1669 }
1670 
1671 
1672 /***********************************************************
1673 **              functions for cdpe_t                      **
1674 ***********************************************************/
1675 
1676 /* normalize both parts: mantissa in [1/2, 1) */
1677 
1678 #define cdpe_Norm(C)  rdpe_Norm (cdpe_Re (C)); rdpe_Norm (cdpe_Im (C));
1679 
1680 /* base constants */
1681 const cdpe_t cdpe_zero = { { { { 0.0, 0L } }, { { 0.0, 0L } } } };
1682 const cdpe_t cdpe_one = { { { { 0.5, 1L } }, { { 0.0, 0L } } } };
1683 const cdpe_t cdpe_i = { { { { 0.0, 0L } }, { { 0.5, 1L } } } };
1684 
1685 void
cdpe_d(cdpe_t temp_cdpe,double r,double i)1686 cdpe_d (cdpe_t temp_cdpe, double r, double i)
1687 /* return (r, i) as a cdpe_t */
1688 {
1689   rdpe_Mnt (cdpe_Re (temp_cdpe)) = r;
1690   rdpe_Esp (cdpe_Re (temp_cdpe)) = 0L;
1691   rdpe_Mnt (cdpe_Im (temp_cdpe)) = i;
1692   rdpe_Esp (cdpe_Im (temp_cdpe)) = 0L;
1693   cdpe_Norm (temp_cdpe);
1694 }
1695 
1696 void
cdpe_x(cdpe_t temp_cdpe,const cplx_t x)1697 cdpe_x (cdpe_t temp_cdpe, const cplx_t x)
1698 /* return x as a cdpe_t */
1699 {
1700   rdpe_Mnt (cdpe_Re (temp_cdpe)) = cplx_Re (x);
1701   rdpe_Esp (cdpe_Re (temp_cdpe)) = 0L;
1702   rdpe_Mnt (cdpe_Im (temp_cdpe)) = cplx_Im (x);
1703   rdpe_Esp (cdpe_Im (temp_cdpe)) = 0L;
1704   cdpe_Norm (temp_cdpe);
1705 }
1706 
1707 void
cdpe_e(cdpe_t temp_cdpe,const rdpe_t er,const rdpe_t ei)1708 cdpe_e (cdpe_t temp_cdpe, const rdpe_t er, const rdpe_t ei)
1709 /* return (er, ei) */
1710 {
1711   rdpe_Move (cdpe_Re (temp_cdpe), er);
1712   rdpe_Move (cdpe_Im (temp_cdpe), ei);
1713 }
1714 
1715 void
cdpe_2dl(cdpe_t temp_cdpe,double dr,long lr,double di,long li)1716 cdpe_2dl (cdpe_t temp_cdpe, double dr, long lr, double di, long li)
1717 /* return (dr*2^lr, di*2^li) as a cdpe_t */
1718 {
1719   rdpe_Mnt (cdpe_Re (temp_cdpe)) = dr;
1720   rdpe_Esp (cdpe_Re (temp_cdpe)) = lr;
1721   rdpe_Mnt (cdpe_Im (temp_cdpe)) = di;
1722   rdpe_Esp (cdpe_Im (temp_cdpe)) = li;
1723   cdpe_Norm (temp_cdpe);
1724 }
1725 
1726 void
cdpe_init(cdpe_t c)1727 cdpe_init (cdpe_t c)
1728 /* c = 0 + I 0 */
1729 {
1730   cdpe_Move (c, cdpe_zero);
1731 }
1732 
1733 void
cdpe_set(cdpe_t rc,const cdpe_t c)1734 cdpe_set (cdpe_t rc, const cdpe_t c)
1735 /* rc = c */
1736 {
1737   cdpe_Move (rc, c);
1738 }
1739 
1740 void
cdpe_set_x(cdpe_t c,const cplx_t x)1741 cdpe_set_x (cdpe_t c, const cplx_t x)
1742 /* c = (cdpe_t) x */
1743 {
1744   cdpe_Move (c, cdpe_zero);
1745   rdpe_Mnt (cdpe_Re (c)) = cplx_Re (x);
1746   rdpe_Mnt (cdpe_Im (c)) = cplx_Im (x);
1747   cdpe_Norm (c);
1748 }
1749 
1750 void
cdpe_set_e(cdpe_t c,const rdpe_t er,const rdpe_t ei)1751 cdpe_set_e (cdpe_t c, const rdpe_t er, const rdpe_t ei)
1752 /* c = er + I ei */
1753 {
1754   rdpe_Move (cdpe_Re (c), er);
1755   rdpe_Move (cdpe_Im (c), ei);
1756 }
1757 
1758 void
cdpe_set_d(cdpe_t c,double dr,double di)1759 cdpe_set_d (cdpe_t c, double dr, double di)
1760 /* c = dr + I di */
1761 {
1762   cdpe_set (c, cdpe_zero);
1763   rdpe_Mnt (cdpe_Re (c)) = dr;
1764   rdpe_Mnt (cdpe_Im (c)) = di;
1765   cdpe_Norm (c);
1766 }
1767 
1768 void
cdpe_set_dl(cdpe_t c,double dr,long int lr,double di,long int li)1769 cdpe_set_dl (cdpe_t c, double dr, long int lr, double di, long int li)
1770 /* c = dr*10^lr + I di*10^li */
1771 {
1772   rdpe_set_dl (cdpe_Re (c), dr, lr);
1773   rdpe_set_dl (cdpe_Im (c), di, li);
1774 }
1775 
1776 void
cdpe_set_2dl(cdpe_t c,double dr,long int lr,double di,long int li)1777 cdpe_set_2dl (cdpe_t c, double dr, long int lr, double di, long int li)
1778 /* c = dr*2^lr + I di*2^li */
1779 {
1780   rdpe_Mnt (cdpe_Re (c)) = dr;
1781   rdpe_Esp (cdpe_Re (c)) = lr;
1782   rdpe_Mnt (cdpe_Im (c)) = di;
1783   rdpe_Esp (cdpe_Im (c)) = li;
1784   cdpe_Norm (c);
1785 }
1786 
1787 int
cdpe_set_str(cdpe_t c,const char * s)1788 cdpe_set_str (cdpe_t c, const char *s)
1789 /* set from string as (re , im) */
1790 {
1791   if (sscanf
1792         (s, CDPE_INP_FMT, &rdpe_Mnt (cdpe_Re (c)), &rdpe_Esp (cdpe_Re (c)),
1793         &rdpe_Mnt (cdpe_Im (c)), &rdpe_Esp (cdpe_Im (c))) != 4)
1794     return 0;
1795   rdpe_set_dl (cdpe_Re (c), rdpe_Mnt (cdpe_Re (c)), rdpe_Esp (cdpe_Re (c)));
1796   rdpe_set_dl (cdpe_Im (c), rdpe_Mnt (cdpe_Im (c)), rdpe_Esp (cdpe_Im (c)));
1797   return 1;
1798 }
1799 
1800 void
cdpe_get_e(rdpe_t er,rdpe_t ei,const cdpe_t c)1801 cdpe_get_e (rdpe_t er, rdpe_t ei, const cdpe_t c)
1802 /* er = re(c), ei = im(c) */
1803 {
1804   rdpe_Move (er, cdpe_Re (c));
1805   rdpe_Move (ei, cdpe_Im (c));
1806 }
1807 
1808 void
cdpe_get_x(cplx_t x,const cdpe_t c)1809 cdpe_get_x (cplx_t x, const cdpe_t c)
1810 /* e = im(c) */
1811 {
1812   cplx_set_d (x,
1813               ldexp (rdpe_Mnt (cdpe_Re (c)), (int)rdpe_Esp (cdpe_Re (c))),
1814               ldexp (rdpe_Mnt (cdpe_Im (c)), (int)rdpe_Esp (cdpe_Im (c))));
1815 }
1816 
1817 void
cdpe_get_d(double * dr,double * di,const cdpe_t c)1818 cdpe_get_d (double *dr, double *di, const cdpe_t c)
1819 /* *dr = re(c), *di = im(c) */
1820 {
1821   *dr = ldexp (rdpe_Mnt (cdpe_Re (c)), (int)rdpe_Esp (cdpe_Re (c)));
1822   *di = ldexp (rdpe_Mnt (cdpe_Im (c)), (int)rdpe_Esp (cdpe_Im (c)));
1823 }
1824 
1825 char *
cdpe_get_str(char * s,const cdpe_t c)1826 cdpe_get_str (char *s, const cdpe_t c)
1827 /* output to string as (re , im) */
1828 {
1829   double dr, di;
1830   long int lr, li;
1831 
1832   if (s == NULL && (s = (char*)mps_malloc (DEF_STR_SIZE)) == NULL)
1833     return NULL;
1834   rdpe_get_dl (&dr, &lr, cdpe_Re (c));
1835   rdpe_get_dl (&di, &li, cdpe_Im (c));
1836   sprintf (s, CDPE_OUT_FMT, dr, lr, di, li);
1837   return s;
1838 }
1839 
1840 void
cdpe_neg(cdpe_t rc,const cdpe_t c)1841 cdpe_neg (cdpe_t rc, const cdpe_t c)
1842 /* rc = -c */
1843 {
1844   cdpe_Move (rc, c);
1845   rdpe_Mnt (cdpe_Re (rc)) = -rdpe_Mnt (cdpe_Re (rc));
1846   rdpe_Mnt (cdpe_Im (rc)) = -rdpe_Mnt (cdpe_Im (rc));
1847 }
1848 
1849 void
cdpe_con(cdpe_t rc,const cdpe_t c)1850 cdpe_con (cdpe_t rc, const cdpe_t c)
1851 /* rc = conj(c) */
1852 {
1853   cdpe_Move (rc, c);
1854   rdpe_Mnt (cdpe_Im (rc)) = -rdpe_Mnt (cdpe_Im (rc));
1855 }
1856 
1857 void
cdpe_smod(rdpe_t e,const cdpe_t c)1858 cdpe_smod (rdpe_t e, const cdpe_t c)
1859 /* e = |c|^2 */
1860 {
1861   rdpe_t t;
1862 
1863   rdpe_sqr (e, cdpe_Re (c));
1864   rdpe_sqr (t, cdpe_Im (c));
1865   rdpe_add_eq (e, t);
1866 }
1867 
1868 void
cdpe_mod(rdpe_t e,const cdpe_t c)1869 cdpe_mod (rdpe_t e, const cdpe_t c)
1870 /* e = |c| */
1871 {
1872   rdpe_t t;
1873 
1874   rdpe_sqr (e, cdpe_Re (c));
1875   rdpe_sqr (t, cdpe_Im (c));
1876   rdpe_add_eq (e, t);
1877   rdpe_sqrt_eq (e);
1878 }
1879 
1880 void
cdpe_inv(cdpe_t rc,const cdpe_t c)1881 cdpe_inv (cdpe_t rc, const cdpe_t c)
1882 /* rc = 1 / c */
1883 {
1884   rdpe_t e;
1885 
1886   cdpe_smod (e, c);
1887   rdpe_inv_eq (e);
1888   cdpe_Move (rc, c);
1889   rdpe_Mnt (cdpe_Im (rc)) = -rdpe_Mnt (cdpe_Im (rc));
1890   rdpe_mul_eq (cdpe_Re (rc), e);
1891   rdpe_mul_eq (cdpe_Im (rc), e);
1892 }
1893 
1894 void
cdpe_sqr(cdpe_t rc,const cdpe_t c)1895 cdpe_sqr (cdpe_t rc, const cdpe_t c)
1896 /* rc = c * c */
1897 {
1898   rdpe_t e1, e2;
1899 
1900   rdpe_mul (e1, cdpe_Re (c), cdpe_Re (c));
1901   rdpe_mul (e2, cdpe_Im (c), cdpe_Im (c));
1902   rdpe_mul (cdpe_Im (rc), cdpe_Im (c), cdpe_Re (c));
1903   rdpe_Esp (cdpe_Im (rc)) += 1; /* multiply by 2 */
1904   rdpe_sub (cdpe_Re (rc), e1, e2);
1905 }
1906 
1907 void
cdpe_rot(cdpe_t rc,const cdpe_t c)1908 cdpe_rot (cdpe_t rc, const cdpe_t c)
1909 /* rc = I c */
1910 {
1911   rdpe_t e;
1912 
1913   rdpe_Move (e, cdpe_Re (c));
1914   rdpe_Move (cdpe_Re (rc), cdpe_Im (c));
1915   rdpe_Move (cdpe_Im (rc), e);
1916   rdpe_Mnt (cdpe_Re (rc)) = -rdpe_Mnt (cdpe_Re (rc));
1917 }
1918 
1919 void
cdpe_flip(cdpe_t rc,const cdpe_t c)1920 cdpe_flip (cdpe_t rc, const cdpe_t c)
1921 /* rc = (Im(c), Re(c)) */
1922 {
1923   rdpe_t e;
1924 
1925   rdpe_Move (e, cdpe_Re (c));
1926   rdpe_Move (cdpe_Re (rc), cdpe_Im (c));
1927   rdpe_Move (cdpe_Im (rc), e);
1928 }
1929 
1930 void
cdpe_add(cdpe_t rc,const cdpe_t c1,const cdpe_t c2)1931 cdpe_add (cdpe_t rc, const cdpe_t c1, const cdpe_t c2)
1932 /* rc = c1 + c2 */
1933 {
1934   rdpe_add (cdpe_Re (rc), cdpe_Re (c1), cdpe_Re (c2));
1935   rdpe_add (cdpe_Im (rc), cdpe_Im (c1), cdpe_Im (c2));
1936 }
1937 
1938 void
cdpe_sub(cdpe_t rc,const cdpe_t c1,const cdpe_t c2)1939 cdpe_sub (cdpe_t rc, const cdpe_t c1, const cdpe_t c2)
1940 /* rc = c1 - c2 */
1941 {
1942   rdpe_sub (cdpe_Re (rc), cdpe_Re (c1), cdpe_Re (c2));
1943   rdpe_sub (cdpe_Im (rc), cdpe_Im (c1), cdpe_Im (c2));
1944 }
1945 
1946 void
cdpe_mul(cdpe_t rc,const cdpe_t c1,const cdpe_t c2)1947 cdpe_mul (cdpe_t rc, const cdpe_t c1, const cdpe_t c2)
1948 /* rc = c1 * c2 */
1949 {
1950   rdpe_t e1, e2, e3;
1951 
1952   rdpe_mul (e1, cdpe_Re (c1), cdpe_Re (c2));
1953   rdpe_mul (e2, cdpe_Im (c1), cdpe_Im (c2));
1954   rdpe_sub (e3, e1, e2);        /* needed when rc=c1 or rc=c2 */
1955   rdpe_mul (e1, cdpe_Im (c1), cdpe_Re (c2));
1956   rdpe_mul (e2, cdpe_Re (c1), cdpe_Im (c2));
1957   rdpe_Move (cdpe_Re (rc), e3);
1958   rdpe_add (cdpe_Im (rc), e1, e2);
1959 }
1960 
1961 void
cdpe_mul_e(cdpe_t rc,const cdpe_t c,const rdpe_t e)1962 cdpe_mul_e (cdpe_t rc, const cdpe_t c, const rdpe_t e)
1963 /* rc = c * e */
1964 {
1965   rdpe_Mnt (cdpe_Re (rc)) = rdpe_Mnt (cdpe_Re (c)) * rdpe_Mnt (e);
1966   rdpe_Esp (cdpe_Re (rc)) = rdpe_Esp (cdpe_Re (c)) + rdpe_Esp (e);
1967   rdpe_Mnt (cdpe_Im (rc)) = rdpe_Mnt (cdpe_Im (c)) * rdpe_Mnt (e);
1968   rdpe_Esp (cdpe_Im (rc)) = rdpe_Esp (cdpe_Im (c)) + rdpe_Esp (e);
1969   cdpe_Norm (rc);
1970 }
1971 
1972 void
cdpe_mul_x(cdpe_t rc,const cdpe_t c,const cplx_t x)1973 cdpe_mul_x (cdpe_t rc, const cdpe_t c, const cplx_t x)
1974 /* rc = c * x */
1975 {
1976   rdpe_t e1, e2, e3;
1977 
1978   rdpe_mul_d (e1, cdpe_Re (c), cplx_Re (x));
1979   rdpe_mul_d (e2, cdpe_Im (c), cplx_Im (x));
1980   rdpe_sub (e3, e1, e2);        /* needed when rc=c1 or rc=c2 */
1981   rdpe_mul_d (e1, cdpe_Im (c), cplx_Re (x));
1982   rdpe_mul_d (e2, cdpe_Re (c), cplx_Im (x));
1983   rdpe_Move (cdpe_Re (rc), e3);
1984   rdpe_add (cdpe_Im (rc), e1, e2);
1985 }
1986 
1987 void
cdpe_mul_d(cdpe_t rc,const cdpe_t c,double d)1988 cdpe_mul_d (cdpe_t rc, const cdpe_t c, double d)
1989 /* rc = c * d */
1990 {
1991   cdpe_Move (rc, c);
1992   rdpe_Mnt (cdpe_Re (rc)) *= d;
1993   rdpe_Mnt (cdpe_Im (rc)) *= d;
1994   cdpe_Norm (rc);
1995 }
1996 
1997 void
cdpe_mul_2exp(cdpe_t rc,const cdpe_t c,unsigned long int i)1998 cdpe_mul_2exp (cdpe_t rc, const cdpe_t c, unsigned long int i)
1999 /* rc = c * 2^i */
2000 {
2001   cdpe_Move (rc, c);
2002   rdpe_Esp (cdpe_Re (rc)) += i;
2003   rdpe_Esp (cdpe_Im (rc)) += i;
2004 }
2005 
2006 void
cdpe_div(cdpe_t rc,const cdpe_t c1,const cdpe_t c2)2007 cdpe_div (cdpe_t rc, const cdpe_t c1, const cdpe_t c2)
2008 /* rc = c1 / c2 */
2009 {
2010   cdpe_t t;                     /* needed when rc=c1 or rc=c2 */
2011   rdpe_t e1, e2, e3;
2012 
2013   cdpe_smod (e1, c2);
2014   cdpe_div_e (t, c2, e1);
2015   rdpe_Mnt (cdpe_Im (t)) = -rdpe_Mnt (cdpe_Im (t));
2016   rdpe_mul (e1, cdpe_Re (c1), cdpe_Re (t));
2017   rdpe_mul (e2, cdpe_Im (c1), cdpe_Im (t));
2018   rdpe_sub (e3, e1, e2);
2019   rdpe_mul (e1, cdpe_Im (c1), cdpe_Re (t));
2020   rdpe_mul (e2, cdpe_Re (c1), cdpe_Im (t));
2021   rdpe_Move (cdpe_Re (rc), e3);
2022   rdpe_add (cdpe_Im (rc), e1, e2);
2023 }
2024 
2025 void
cdpe_div_e(cdpe_t rc,const cdpe_t c,const rdpe_t e)2026 cdpe_div_e (cdpe_t rc, const cdpe_t c, const rdpe_t e)
2027 /* rc = c / e */
2028 {
2029   rdpe_Mnt (cdpe_Re (rc)) = rdpe_Mnt (cdpe_Re (c)) / rdpe_Mnt (e);
2030   rdpe_Esp (cdpe_Re (rc)) = rdpe_Esp (cdpe_Re (c)) - rdpe_Esp (e);
2031   rdpe_Mnt (cdpe_Im (rc)) = rdpe_Mnt (cdpe_Im (c)) / rdpe_Mnt (e);
2032   rdpe_Esp (cdpe_Im (rc)) = rdpe_Esp (cdpe_Im (c)) - rdpe_Esp (e);
2033   cdpe_Norm (rc);
2034 }
2035 
2036 void
cdpe_div_d(cdpe_t rc,const cdpe_t c,double d)2037 cdpe_div_d (cdpe_t rc, const cdpe_t c, double d)
2038 /* rc = c / d */
2039 {
2040   cdpe_Move (rc, c);
2041   rdpe_Mnt (cdpe_Re (rc)) /= d;
2042   rdpe_Mnt (cdpe_Im (rc)) /= d;
2043   cdpe_Norm (rc);
2044 }
2045 
2046 void
cdpe_div_2exp(cdpe_t rc,const cdpe_t c,unsigned long int i)2047 cdpe_div_2exp (cdpe_t rc, const cdpe_t c, unsigned long int i)
2048 /* rc = c / 2^i */
2049 {
2050   cdpe_Move (rc, c);
2051   rdpe_Esp (cdpe_Re (rc)) -= i;
2052   rdpe_Esp (cdpe_Im (rc)) -= i;
2053 }
2054 
2055 void
cdpe_pow_si(cdpe_t rc,const cdpe_t c,register signed long int i)2056 cdpe_pow_si (cdpe_t rc, const cdpe_t c, register signed long int i)
2057 /* rc = c^i, i integer */
2058 {
2059   cdpe_t t;
2060 
2061   cdpe_Move (t, c);
2062   cdpe_Move (rc, cdpe_one);
2063 
2064   if (i < 0)
2065     {
2066       cdpe_inv (t, t);
2067       i = -i;
2068     }
2069   while (i)
2070     {
2071       if (i & 1)
2072         cdpe_mul_eq (rc, t);
2073       cdpe_sqr_eq (t);
2074       i >>= 1;                  /* divide i by 2 */
2075     }
2076 }
2077 
2078 void
cdpe_swap(cdpe_t c1,cdpe_t c2)2079 cdpe_swap (cdpe_t c1, cdpe_t c2)
2080 /* c1 <-> c2 */
2081 {
2082   cdpe_t t;
2083 
2084   cdpe_Move (t, c1);
2085   cdpe_Move (c1, c2);
2086   cdpe_Move (c2, t);
2087 }
2088 
2089 void
cdpe_neg_eq(cdpe_t c)2090 cdpe_neg_eq (cdpe_t c)
2091 /* c = -c */
2092 {
2093   rdpe_Mnt (cdpe_Re (c)) = -rdpe_Mnt (cdpe_Re (c));
2094   rdpe_Mnt (cdpe_Im (c)) = -rdpe_Mnt (cdpe_Im (c));
2095 }
2096 
2097 void
cdpe_con_eq(cdpe_t c)2098 cdpe_con_eq (cdpe_t c)
2099 /* c = conj(c) */
2100 {
2101   rdpe_Mnt (cdpe_Im (c)) = -rdpe_Mnt (cdpe_Im (c));
2102 }
2103 
2104 void
cdpe_inv_eq(cdpe_t c)2105 cdpe_inv_eq (cdpe_t c)
2106 /* c = 1 / c */
2107 {
2108   rdpe_t e;
2109 
2110   cdpe_smod (e, c);
2111   rdpe_inv_eq (e);
2112   rdpe_Mnt (cdpe_Im (c)) = -rdpe_Mnt (cdpe_Im (c));
2113   rdpe_mul_eq (cdpe_Re (c), e);
2114   rdpe_mul_eq (cdpe_Im (c), e);
2115 }
2116 
2117 void
cdpe_sqr_eq(cdpe_t c)2118 cdpe_sqr_eq (cdpe_t c)
2119 /* c = c * c */
2120 {
2121   rdpe_t e1, e2;
2122 
2123   rdpe_sqr (e1, cdpe_Re (c));
2124   rdpe_sqr (e2, cdpe_Im (c));
2125   rdpe_mul_eq (cdpe_Im (c), cdpe_Re (c));
2126   rdpe_Esp (cdpe_Im (c)) += 1;  /* multiply by 2 */
2127   rdpe_sub (cdpe_Re (c), e1, e2);
2128 }
2129 
2130 void
cdpe_rot_eq(cdpe_t c)2131 cdpe_rot_eq (cdpe_t c)
2132 /* c = I c */
2133 {
2134   rdpe_t e;
2135 
2136   rdpe_Move (e, cdpe_Re (c));
2137   rdpe_Move (cdpe_Re (c), cdpe_Im (c));
2138   rdpe_Move (cdpe_Im (c), e);
2139   rdpe_Mnt (cdpe_Re (c)) = -rdpe_Mnt (cdpe_Re (c));
2140 }
2141 
2142 void
cdpe_flip_eq(cdpe_t c)2143 cdpe_flip_eq (cdpe_t c)
2144 /* c = (Im(c), Re(c)) */
2145 {
2146   rdpe_t e;
2147 
2148   rdpe_Move (e, cdpe_Re (c));
2149   rdpe_Move (cdpe_Re (c), cdpe_Im (c));
2150   rdpe_Move (cdpe_Im (c), e);
2151 }
2152 
2153 void
cdpe_add_eq(cdpe_t rc,const cdpe_t c)2154 cdpe_add_eq (cdpe_t rc, const cdpe_t c)
2155 /* rc = rc + c2 */
2156 {
2157   rdpe_add_eq (cdpe_Re (rc), cdpe_Re (c));
2158   rdpe_add_eq (cdpe_Im (rc), cdpe_Im (c));
2159 }
2160 
2161 void
cdpe_sub_eq(cdpe_t rc,const cdpe_t c)2162 cdpe_sub_eq (cdpe_t rc, const cdpe_t c)
2163 /* rc = rc - c2 */
2164 {
2165   rdpe_sub_eq (cdpe_Re (rc), cdpe_Re (c));
2166   rdpe_sub_eq (cdpe_Im (rc), cdpe_Im (c));
2167 }
2168 
2169 void
cdpe_mul_eq(cdpe_t rc,const cdpe_t c)2170 cdpe_mul_eq (cdpe_t rc, const cdpe_t c)
2171 /* rc = rc * c */
2172 {
2173   rdpe_t e1, e2, e3;
2174 
2175   rdpe_mul (e1, cdpe_Re (rc), cdpe_Re (c));
2176   rdpe_mul (e2, cdpe_Im (rc), cdpe_Im (c));
2177   rdpe_sub (e3, e1, e2);
2178   rdpe_mul (e1, cdpe_Im (rc), cdpe_Re (c));
2179   rdpe_mul (e2, cdpe_Re (rc), cdpe_Im (c));
2180   rdpe_Move (cdpe_Re (rc), e3);
2181   rdpe_add (cdpe_Im (rc), e1, e2);
2182 }
2183 
2184 void
cdpe_mul_eq_e(cdpe_t c,const rdpe_t e)2185 cdpe_mul_eq_e (cdpe_t c, const rdpe_t e)
2186 /* c = c * e */
2187 {
2188   rdpe_Mnt (cdpe_Re (c)) *= rdpe_Mnt (e);
2189   rdpe_Esp (cdpe_Re (c)) += rdpe_Esp (e);
2190   rdpe_Mnt (cdpe_Im (c)) *= rdpe_Mnt (e);
2191   rdpe_Esp (cdpe_Im (c)) += rdpe_Esp (e);
2192   cdpe_Norm (c);
2193 }
2194 
2195 void
cdpe_mul_eq_x(cdpe_t c,const cplx_t x)2196 cdpe_mul_eq_x (cdpe_t c, const cplx_t x)
2197 /* c *= x */
2198 {
2199   rdpe_t e1, e2, e3;
2200 
2201   rdpe_mul_d (e1, cdpe_Re (c), cplx_Re (x));
2202   rdpe_mul_d (e2, cdpe_Im (c), cplx_Im (x));
2203   rdpe_sub (e3, e1, e2);        /* needed when rc=c1 or rc=c2 */
2204   rdpe_mul_d (e1, cdpe_Im (c), cplx_Re (x));
2205   rdpe_mul_d (e2, cdpe_Re (c), cplx_Im (x));
2206   rdpe_Move (cdpe_Re (c), e3);
2207   rdpe_add (cdpe_Im (c), e1, e2);
2208 }
2209 
2210 void
cdpe_mul_eq_d(cdpe_t c,double d)2211 cdpe_mul_eq_d (cdpe_t c, double d)
2212 /* c = c * d */
2213 {
2214   rdpe_Mnt (cdpe_Re (c)) *= d;
2215   rdpe_Mnt (cdpe_Im (c)) *= d;
2216   cdpe_Norm (c);
2217 }
2218 
2219 void
cdpe_mul_eq_2exp(cdpe_t c,unsigned long int i)2220 cdpe_mul_eq_2exp (cdpe_t c, unsigned long int i)
2221 /* c = c * 2^i */
2222 {
2223   rdpe_Esp (cdpe_Re (c)) += i;
2224   rdpe_Esp (cdpe_Im (c)) += i;
2225 }
2226 
2227 void
cdpe_div_eq(cdpe_t rc,const cdpe_t c)2228 cdpe_div_eq (cdpe_t rc, const cdpe_t c)
2229 /* rc = rc / c */
2230 {
2231   cdpe_t t;
2232   rdpe_t e1, e2, e3;
2233 
2234   cdpe_smod (e1, c);
2235   cdpe_div_e (t, c, e1);
2236   rdpe_Mnt (cdpe_Im (t)) = -rdpe_Mnt (cdpe_Im (t));
2237   rdpe_mul (e1, cdpe_Re (c), cdpe_Re (t));
2238   rdpe_mul (e2, cdpe_Im (c), cdpe_Im (t));
2239   rdpe_sub (e3, e1, e2);
2240   rdpe_mul (e1, cdpe_Im (c), cdpe_Re (t));
2241   rdpe_mul (e2, cdpe_Re (c), cdpe_Im (t));
2242   rdpe_Move (cdpe_Re (rc), e3);
2243   rdpe_add (cdpe_Im (rc), e1, e2);
2244 }
2245 
2246 void
cdpe_div_eq_e(cdpe_t c,const rdpe_t e)2247 cdpe_div_eq_e (cdpe_t c, const rdpe_t e)
2248 /* c = c / e */
2249 {
2250   rdpe_Mnt (cdpe_Re (c)) /= rdpe_Mnt (e);
2251   rdpe_Esp (cdpe_Re (c)) -= rdpe_Esp (e);
2252   rdpe_Mnt (cdpe_Im (c)) /= rdpe_Mnt (e);
2253   rdpe_Esp (cdpe_Im (c)) -= rdpe_Esp (e);
2254   cdpe_Norm (c);
2255 }
2256 
2257 void
cdpe_div_eq_d(cdpe_t c,double d)2258 cdpe_div_eq_d (cdpe_t c, double d)
2259 /* c = c / d */
2260 {
2261   rdpe_Mnt (cdpe_Re (c)) /= d;
2262   rdpe_Mnt (cdpe_Im (c)) /= d;
2263   cdpe_Norm (c);
2264 }
2265 
2266 void
cdpe_div_eq_2exp(cdpe_t c,unsigned long int i)2267 cdpe_div_eq_2exp (cdpe_t c, unsigned long int i)
2268 /* c = c / 2^i */
2269 {
2270   rdpe_Esp (cdpe_Re (c)) -= i;
2271   rdpe_Esp (cdpe_Im (c)) -= i;
2272 }
2273 
2274 void
cdpe_pow_eq_si(cdpe_t c,register signed long int i)2275 cdpe_pow_eq_si (cdpe_t c, register signed long int i)
2276 /* rc = c^i, i integer */
2277 {
2278   cdpe_t t;
2279 
2280   cdpe_Move (t, c);
2281   cdpe_Move (c, cdpe_one);
2282 
2283   if (i < 0)
2284     {
2285       cdpe_inv (t, t);
2286       i = -i;
2287     }
2288   while (i)
2289     {
2290       if (i & 1)
2291         cdpe_mul_eq (c, t);
2292       cdpe_sqr_eq (t);
2293       i >>= 1;                  /* divide i by 2 */
2294     }
2295 }
2296 
2297 /*------------  relational ops.  -------------------------*/
2298 
2299 int
cdpe_eq_zero(const cdpe_t c)2300 cdpe_eq_zero (const cdpe_t c)
2301 /* c == 0 */
2302 {
2303   return rdpe_Mnt (cdpe_Re (c)) == 0.0 && rdpe_Esp (cdpe_Re (c)) == 0 &&
2304          rdpe_Mnt (cdpe_Im (c)) == 0.0 && rdpe_Esp (cdpe_Im (c)) == 0;
2305 }
2306 
2307 int
cdpe_eq(const cdpe_t c1,const cdpe_t c2)2308 cdpe_eq (const cdpe_t c1, const cdpe_t c2)
2309 /* c1 == c2 */
2310 {
2311   return rdpe_Mnt (cdpe_Re (c1)) == rdpe_Mnt (cdpe_Re (c2)) &&
2312          rdpe_Esp (cdpe_Re (c1)) == rdpe_Esp (cdpe_Re (c2)) &&
2313          rdpe_Mnt (cdpe_Im (c1)) == rdpe_Mnt (cdpe_Im (c2)) &&
2314          rdpe_Esp (cdpe_Im (c1)) == rdpe_Esp (cdpe_Im (c2));
2315 }
2316 
2317 int
cdpe_ne(const cdpe_t c1,const cdpe_t c2)2318 cdpe_ne (const cdpe_t c1, const cdpe_t c2)
2319 /* c1 != c2 */
2320 {
2321   return rdpe_Mnt (cdpe_Re (c1)) != rdpe_Mnt (cdpe_Re (c2)) ||
2322          rdpe_Esp (cdpe_Re (c1)) != rdpe_Esp (cdpe_Re (c2)) ||
2323          rdpe_Mnt (cdpe_Im (c1)) != rdpe_Mnt (cdpe_Im (c2)) ||
2324          rdpe_Esp (cdpe_Im (c1)) != rdpe_Esp (cdpe_Im (c2));
2325 }
2326 
2327 /*------------  I/O functions  ---------------------------*/
2328 
2329 int
cdpe_out_str_u(FILE * f,const cdpe_t c)2330 cdpe_out_str_u (FILE * f, const cdpe_t c)
2331 /* output as mant e exp  mant e exp  */
2332 {
2333   if (f == NULL)
2334     f = stdout;
2335   if (rdpe_out_str_u (f, cdpe_Re (c)) < 0)
2336     return -1;
2337   if (fprintf (f, " ") < 0)
2338     return -1;
2339   if (rdpe_out_str_u (f, cdpe_Im (c)) < 0)
2340     return -1;
2341   return 0;
2342 }
2343 
2344 int
cdpe_out_str(FILE * f,const cdpe_t c)2345 cdpe_out_str (FILE * f, const cdpe_t c)
2346 /* output as (mant x exp , mant x exp)  */
2347 {
2348   if (f == NULL)
2349     f = stdout;
2350   if (fputc ('(', f) == EOF)
2351     return -1;
2352   if (rdpe_out_str (f, cdpe_Re (c)) < 0)
2353     return -1;
2354   if (fprintf (f, ", ") < 0)
2355     return -1;
2356   if (rdpe_out_str (f, cdpe_Im (c)) < 0)
2357     return -1;
2358   return fputc (')', f);
2359 }
2360 
2361 int
cdpe_inp_str_u(cdpe_t c,FILE * f)2362 cdpe_inp_str_u (cdpe_t c, FILE * f)
2363 /* input from file as mant e exp  mant e exp */
2364 {
2365   double dr, di;
2366   long int lr, li;
2367 
2368   if (f == NULL)
2369     f = stdin;
2370   if (fscanf (f, CDPE_INP_UFMT, &dr, &lr, &di, &li) != 4)
2371     return 0;
2372   rdpe_set_dl (cdpe_Re (c), dr, lr);
2373   rdpe_set_dl (cdpe_Im (c), di, li);
2374   return 1;
2375 }
2376 
2377 int
cdpe_inp_str(cdpe_t c,FILE * f)2378 cdpe_inp_str (cdpe_t c, FILE * f)
2379 /* input from file as (mant x exp , mant x exp) */
2380 {
2381   double dr, di;
2382   long int lr, li;
2383 
2384   if (f == NULL)
2385     f = stdin;
2386   if (fscanf (f, CDPE_INP_FMT, &dr, &lr, &di, &li) != 4)
2387     return 0;
2388   rdpe_set_dl (cdpe_Re (c), dr, lr);
2389   rdpe_set_dl (cdpe_Im (c), di, li);
2390   return 1;
2391 }
2392 
2393 /*------------  vector functions  ------------------------*/
2394 
2395 void
cdpe_vinit(cdpe_t v[],long size)2396 cdpe_vinit (cdpe_t v[], long size)
2397 {
2398   long i;
2399 
2400   for (i = 0; i < size; i++)
2401     cdpe_Move (v[i], cdpe_zero);
2402 }
2403 
2404 /***********************************************************
2405 **                                                        **
2406 ***********************************************************/
2407