a68g-mp.h

     
   1  //! @file a68g-mp.h
   2  //! @author J. Marcel van der Veer
   3  //!
   4  //! @section Copyright
   5  //!
   6  //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
   7  //! Copyright 2001-2023 J. Marcel van der Veer [algol68g@xs4all.nl].
   8  //!
   9  //! @section License
  10  //!
  11  //! This program is free software; you can redistribute it and/or modify it 
  12  //! under the terms of the GNU General Public License as published by the 
  13  //! Free Software Foundation; either version 3 of the License, or 
  14  //! (at your option) any later version.
  15  //!
  16  //! This program is distributed in the hope that it will be useful, but 
  17  //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  18  //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  19  //! more details. You should have received a copy of the GNU General Public 
  20  //! License along with this program. If not, see [http://www.gnu.org/licenses/].
  21  
  22  #if !defined (__A68G_MP_H__)
  23  #define __A68G_MP_H__
  24  
  25  // A68G's multiprecision algorithms are not suited for more than a few hundred
  26  // digits. This is however sufficient for most practical MP applications.
  27  
  28  #define MP_MAX_DECIMALS 250
  29  #define MP_MAX_DIGITS (1 + MP_MAX_DECIMALS / LOG_MP_RADIX)
  30  
  31  #define MP_STATUS(z) ((z)[0])
  32  #define MP_EXPONENT(z) ((z)[1])
  33  #define MP_DIGIT(z, n) ((z)[(n) + 1])
  34  #define MP_SIGN(z) (SIGN (MP_DIGIT (z, 1)))
  35  #define LEN_MP(digs) (2 + digs)
  36  #define SIZE_MP(digs) A68_ALIGN (LEN_MP (digs) * sizeof (MP_T))
  37  #define IS_ZERO_MP(z) (MP_DIGIT (z, 1) == (MP_T) 0)
  38  
  39  #define PLUS_INF_MP(u) ((UNSIGNED_T) MP_STATUS (u) & PLUS_INF_MASK)
  40  #define MINUS_INF_MP(u) ((UNSIGNED_T) MP_STATUS (u) & MINUS_INF_MASK)
  41  #define INF_MP(u) (PLUS_INF_MP (u) || MINUS_INF_MP (u))
  42  #define CHECK_LONG_REAL(p, u, moid) PRELUDE_ERROR (INF_MP (u), p, ERROR_INFINITE, moid)
  43  
  44  static inline MP_T *set_mp (MP_T * z, MP_T x, INT_T expo, int digs)
  45  {
  46    memset (z, 0, SIZE_MP (digs));
  47    MP_STATUS (z) = (MP_T) INIT_MASK;
  48    MP_DIGIT (z, 1) = x;
  49    MP_EXPONENT (z) = (MP_T) expo;
  50    return z;
  51  }
  52  
  53  static inline MP_T *move_mp (MP_T *z, MP_T *x, int N) 
  54  {
  55    MP_T *y = z;
  56    N += 2;
  57    while (N--) {
  58      *z++ = *x++;
  59    }
  60    return y;
  61  }
  62  
  63  static inline MP_T *move_mp_part (MP_T *z, MP_T *x, int N) 
  64  {
  65    MP_T *y = z;
  66    while (N--) {
  67      *z++ = *x++;
  68    }
  69    return y;
  70  }
  71  
  72  static inline void check_mp_exp (NODE_T *p, MP_T *z) 
  73  {
  74    MP_T expo = (MP_EXPONENT (z) < 0 ? -MP_EXPONENT (z) : MP_EXPONENT (z));
  75    if (expo > MAX_MP_EXPONENT || (expo == MAX_MP_EXPONENT && ABS (MP_DIGIT (z, 1)) > (MP_T) 1)) {
  76      errno = EDOM;
  77      diagnostic (A68_RUNTIME_ERROR, p, ERROR_MP_OUT_OF_BOUNDS, NULL);
  78      extern void exit_genie (NODE_T *, int);
  79      exit_genie (p, A68_RUNTIME_ERROR);
  80    }
  81  }
  82  
  83  static inline MP_T *mp_one (int digs)
  84  {
  85    if (digs > A68_MP (mp_one_size)) {
  86      if (A68_MP (mp_one) != (MP_T *) NULL) {
  87        a68_free (A68_MP (mp_one));
  88      }
  89      A68_MP (mp_one) = (MP_T *) get_heap_space (SIZE_MP (digs));
  90      set_mp (A68_MP (mp_one), 1, 0, digs);
  91    }
  92    return A68_MP (mp_one);
  93  }
  94  
  95  static inline MP_T *lit_mp (NODE_T *p, MP_T u, INT_T expo, int digs)
  96  {
  97    ADDR_T pop_sp = A68_SP;
  98    if ((A68_SP += SIZE_MP (digs)) > A68 (expr_stack_limit)) {
  99      diagnostic (A68_RUNTIME_ERROR, p, ERROR_STACK_OVERFLOW);
 100      extern void exit_genie (NODE_T *, int);
 101      exit_genie (p, A68_RUNTIME_ERROR);
 102    }
 103    MP_T *z = (MP_T *) STACK_ADDRESS (pop_sp);
 104    (void) set_mp (z, u, expo, digs);
 105    return z;
 106  }
 107  
 108  static inline MP_T *nil_mp (NODE_T *p, int digs)
 109  {
 110    ADDR_T pop_sp = A68_SP;
 111    if ((A68_SP += SIZE_MP (digs)) > A68 (expr_stack_limit)) {
 112      diagnostic (A68_RUNTIME_ERROR, p, ERROR_STACK_OVERFLOW);
 113      extern void exit_genie (NODE_T *, int);
 114      exit_genie (p, A68_RUNTIME_ERROR);
 115    }
 116    MP_T *z = (MP_T *) STACK_ADDRESS (pop_sp);
 117    (void) set_mp (z, 0, 0, digs);
 118    return z;
 119  }
 120  
 121  static inline MP_T *empty_mp (NODE_T *p, int digs)
 122  {
 123    ADDR_T pop_sp = A68_SP;
 124    if ((A68_SP += SIZE_MP (digs)) > A68 (expr_stack_limit)) {
 125      diagnostic (A68_RUNTIME_ERROR, p, ERROR_STACK_OVERFLOW);
 126      extern void exit_genie (NODE_T *, int);
 127      exit_genie (p, A68_RUNTIME_ERROR);
 128    }
 129    return (MP_T *) STACK_ADDRESS (pop_sp);
 130  }
 131  
 132  extern MP_T *lengthen_mp (NODE_T *, MP_T *, int, MP_T *, int);
 133  
 134  static inline MP_T *len_mp (NODE_T *p, MP_T *u, int digs, int gdigs)
 135  {
 136    ADDR_T pop_sp = A68_SP;
 137    if ((A68_SP += SIZE_MP (gdigs)) > A68 (expr_stack_limit)) {
 138      diagnostic (A68_RUNTIME_ERROR, p, ERROR_STACK_OVERFLOW);
 139      extern void exit_genie (NODE_T *, int);
 140      exit_genie (p, A68_RUNTIME_ERROR);
 141    }
 142    MP_T *z = (MP_T *) STACK_ADDRESS (pop_sp);
 143    for (int k = 1; k <= digs; k++) {
 144      MP_DIGIT (z, k) = MP_DIGIT (u, k);
 145    }
 146    for (int k = digs + 1; k <= gdigs; k++) {
 147      MP_DIGIT (z, k) = (MP_T) 0;
 148    }
 149    MP_EXPONENT (z) = MP_EXPONENT (u);
 150    MP_STATUS (z) = MP_STATUS (u);
 151    return z;
 152  }
 153  
 154  static inline MP_T *cut_mp (NODE_T *p, MP_T *u, int digs, int gdigs)
 155  {
 156    ADDR_T pop_sp = A68_SP;
 157    ASSERT (digs > gdigs);
 158    BOOL_T neg = MP_DIGIT (u, 1) < 0;
 159    if ((A68_SP += SIZE_MP (gdigs)) > A68 (expr_stack_limit)) {
 160      diagnostic (A68_RUNTIME_ERROR, p, ERROR_STACK_OVERFLOW);
 161      extern void exit_genie (NODE_T *, int);
 162      exit_genie (p, A68_RUNTIME_ERROR);
 163    }
 164    MP_T *z = (MP_T *) STACK_ADDRESS (pop_sp);
 165    for (int k = 1; k <= gdigs; k++) {
 166      MP_DIGIT (z, k) = MP_DIGIT (u, k);
 167    }
 168    if (neg) {
 169      MP_DIGIT (z, 1) = -MP_DIGIT (z, 1);
 170    }
 171    if (MP_DIGIT (u, gdigs + 1) >= MP_RADIX / 2) {
 172      MP_DIGIT (z, gdigs) += 1;
 173      for (int k = digs; k >= 2 && MP_DIGIT (z, k) == MP_RADIX; k --) {
 174        MP_DIGIT (z, k) = 0;
 175        MP_DIGIT (z, k - 1) ++;
 176      }
 177    }
 178    if (neg) {
 179      MP_DIGIT (z, 1) = -MP_DIGIT (z, 1);
 180    }
 181    MP_EXPONENT (z) = MP_EXPONENT (u);
 182    MP_STATUS (z) = MP_STATUS (u);
 183    return z;
 184  }
 185  
 186  //! @brief Length in bytes of a long mp number.
 187  
 188  static inline size_t size_mp (void)
 189  {
 190    return (size_t) SIZE_MP (LONG_MP_DIGITS);
 191  }
 192  
 193  //! @brief Length in digits of a long mp number.
 194  
 195  static inline int mp_digits (void)
 196  {
 197    return LONG_MP_DIGITS;
 198  }
 199  
 200  //! @brief Length in bytes of a long long mp number.
 201  
 202  static inline size_t size_long_mp (void)
 203  {
 204    return (size_t) (SIZE_MP (A68_MP (varying_mp_digits)));
 205  }
 206  
 207  //! @brief digits in a long mp number.
 208  
 209  static inline int long_mp_digits (void)
 210  {
 211    return A68_MP (varying_mp_digits);
 212  }
 213  
 214  #define SET_MP_ZERO(z, digits)\
 215    (void) set_mp ((z), 0, 0, digits);
 216  
 217  #define SET_MP_ONE(z, digits)\
 218    (void) set_mp ((z), (MP_T) 1, 0, digits);
 219  
 220  #define SET_MP_MINUS_ONE(z, digits)\
 221    (void) set_mp ((z), (MP_T) -1, 0, digits);
 222  
 223  #define SET_MP_HALF(z, digits)\
 224    (void) set_mp ((z), (MP_T) (MP_RADIX / 2), -1, digits);
 225  
 226  #define SET_MP_MINUS_HALF(z, digits)\
 227    (void) set_mp ((z), (MP_T) -(MP_RADIX / 2), -1, digits);
 228  
 229  #define SET_MP_QUART(z, digits)\
 230    (void) set_mp ((z), (MP_T) (MP_RADIX / 4), -1, digits);
 231  
 232  enum {MP_SQRT_PI, MP_PI, MP_LN_PI, MP_SQRT_TWO_PI, MP_TWO_PI, MP_HALF_PI, MP_180_OVER_PI, MP_PI_OVER_180};
 233  
 234  // If MP_DOUBLE_PRECISION is defined functions are evaluated in double precision.
 235  
 236  #undef MP_DOUBLE_PRECISION
 237  
 238  #define MINIMUM(x, y) ((x) < (y) ? (x) : (y))
 239  
 240  // GUARD_DIGITS: number of guard digits.
 241  
 242  #if defined (MP_DOUBLE_PRECISION)
 243  #define GUARD_DIGITS(digits) (digits)
 244  #else
 245  #define GUARD_DIGITS(digits) (2)
 246  #endif
 247  
 248  #define FUN_DIGITS(n) ((n) + GUARD_DIGITS (n))
 249  
 250  // External multi-precision procedures
 251  
 252  extern BOOL_T check_mp_int (MP_T *, MOID_T *);
 253  extern BOOL_T is_int_mp (NODE_T *p, MP_T *z, int digits);
 254  extern BOOL_T same_mp (NODE_T *, MP_T *, MP_T *, int);
 255  extern int long_mp_digits (void);
 256  extern INT_T mp_to_int (NODE_T *, MP_T *, int);
 257  extern int width_to_mp_digits (int);
 258  extern MP_T *abs_mp (NODE_T *, MP_T *, MP_T *, int);
 259  extern MP_T *acosdg_mp (NODE_T *, MP_T *, MP_T *, int);
 260  extern MP_T *acosh_mp (NODE_T *, MP_T *, MP_T *, int);
 261  extern MP_T *acos_mp (NODE_T *, MP_T *, MP_T *, int);
 262  extern MP_T *acotdg_mp (NODE_T *, MP_T *, MP_T *, int);
 263  extern MP_T *acot_mp (NODE_T *, MP_T *, MP_T *, int);
 264  extern MP_T *acsc_mp (NODE_T *, MP_T *, MP_T *, int);
 265  extern MP_T *add_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 266  extern MP_T *align_mp (MP_T *, INT_T *, int);
 267  extern MP_T *asec_mp (NODE_T *, MP_T *, MP_T *, int);
 268  extern MP_T *asindg_mp (NODE_T *, MP_T *, MP_T *, int);
 269  extern MP_T *asinh_mp (NODE_T *, MP_T *, MP_T *, int);
 270  extern MP_T *asin_mp (NODE_T *, MP_T *, MP_T *, int);
 271  extern MP_T *atan2dg_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 272  extern MP_T *atan2_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 273  extern MP_T *atandg_mp (NODE_T *, MP_T *, MP_T *, int);
 274  extern MP_T *atanh_mp (NODE_T *, MP_T *, MP_T *, int);
 275  extern MP_T *atan_mp (NODE_T *, MP_T *, MP_T *, int);
 276  extern MP_T *beta_inc_mp (NODE_T *, MP_T *, MP_T *, MP_T *, MP_T *, int);
 277  extern MP_T *beta_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 278  extern MP_T *cacosh_mp (NODE_T *, MP_T *, MP_T *, int);
 279  extern MP_T *cacos_mp (NODE_T *, MP_T *, MP_T *, int);
 280  extern MP_T *casinh_mp (NODE_T *, MP_T *, MP_T *, int);
 281  extern MP_T *casin_mp (NODE_T *, MP_T *, MP_T *, int);
 282  extern MP_T *catanh_mp (NODE_T *, MP_T *, MP_T *, int);
 283  extern MP_T *catan_mp (NODE_T *, MP_T *, MP_T *, int);
 284  extern MP_T *ccosh_mp (NODE_T *, MP_T *, MP_T *, int);
 285  extern MP_T *ccos_mp (NODE_T *, MP_T *, MP_T *, int);
 286  extern MP_T *cdiv_mp (NODE_T *, MP_T *, MP_T *, MP_T *, MP_T *, int);
 287  extern MP_T *cexp_mp (NODE_T *, MP_T *, MP_T *, int);
 288  extern MP_T *cln_mp (NODE_T *, MP_T *, MP_T *, int);
 289  extern MP_T *cmul_mp (NODE_T *, MP_T *, MP_T *, MP_T *, MP_T *, int);
 290  extern MP_T *cosdg_mp (NODE_T *, MP_T *, MP_T *, int);
 291  extern MP_T *cosh_mp (NODE_T *, MP_T *, MP_T *, int);
 292  extern MP_T *cos_mp (NODE_T *, MP_T *, MP_T *, int);
 293  extern MP_T *cospi_mp (NODE_T *, MP_T *, MP_T *, int);
 294  extern MP_T *cotdg_mp (NODE_T *, MP_T *, MP_T *, int);
 295  extern MP_T *cot_mp (NODE_T *, MP_T *, MP_T *, int);
 296  extern MP_T *cotpi_mp (NODE_T *, MP_T *, MP_T *, int);
 297  extern MP_T *csc_mp (NODE_T *, MP_T *, MP_T *, int);
 298  extern MP_T *csinh_mp (NODE_T *, MP_T *, MP_T *, int);
 299  extern MP_T *csin_mp (NODE_T *, MP_T *, MP_T *, int);
 300  extern MP_T *csqrt_mp (NODE_T *, MP_T *, MP_T *, int);
 301  extern MP_T *ctanh_mp (NODE_T *, MP_T *, MP_T *, int);
 302  extern MP_T *ctan_mp (NODE_T *, MP_T *, MP_T *, int);
 303  extern MP_T *curt_mp (NODE_T *, MP_T *, MP_T *, int);
 304  extern MP_T *div_mp_digit (NODE_T *, MP_T *, MP_T *, MP_T, int);
 305  extern MP_T *div_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 306  extern MP_T *entier_mp (NODE_T *, MP_T *, MP_T *, int);
 307  extern MP_T *erfc_mp (NODE_T *, MP_T *, MP_T *, int);
 308  extern MP_T *erf_mp (NODE_T *, MP_T *, MP_T *, int);
 309  extern MP_T *expm1_mp (NODE_T *, MP_T *, MP_T *, int);
 310  extern MP_T *exp_mp (NODE_T *, MP_T *, MP_T *, int);
 311  extern MP_T *floor_mp (NODE_T *, MP_T *, MP_T *, int);
 312  extern MP_T *gamma_inc_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 313  extern MP_T *gamma_mp (NODE_T *, MP_T *, MP_T *, int);
 314  extern MP_T *half_mp (NODE_T *, MP_T *, MP_T *, int);
 315  extern MP_T *hyp_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 316  extern MP_T *hypot_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 317  extern MP_T *int_to_mp (NODE_T *, MP_T *, INT_T, int);
 318  extern MP_T *inverfc_mp (NODE_T *, MP_T *, MP_T *, int);
 319  extern MP_T *inverf_mp (NODE_T *, MP_T *, MP_T *, int);
 320  extern MP_T *lnbeta_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 321  extern MP_T *lngamma_mp (NODE_T *, MP_T *, MP_T *, int);
 322  extern MP_T *ln_mp (NODE_T *, MP_T *, MP_T *, int);
 323  extern MP_T *log_mp (NODE_T *, MP_T *, MP_T *, int);
 324  extern MP_T *minus_mp (NODE_T *, MP_T *, MP_T *, int);
 325  extern MP_T *minus_one_mp (NODE_T *, MP_T *, MP_T *, int);
 326  extern MP_T *mod_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 327  extern MP_T *mp_ln_10 (NODE_T *, MP_T *, int);
 328  extern MP_T *mp_ln_scale (NODE_T *, MP_T *, int);
 329  extern MP_T *mp_pi (NODE_T *, MP_T *, int, int);
 330  extern MP_T *ten_up_mp (NODE_T *, MP_T *, int, int);
 331  extern MP_T *mul_mp_digit (NODE_T *, MP_T *, MP_T *, MP_T, int);
 332  extern MP_T *mul_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 333  extern MP_T *one_minus_mp (NODE_T *, MP_T *, MP_T *, int);
 334  extern MP_T *over_mp_digit (NODE_T *, MP_T *, MP_T *, MP_T, int);
 335  extern MP_T *over_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 336  extern MP_T *plus_one_mp (NODE_T *, MP_T *, MP_T *, int);
 337  extern MP_T *pow_mp_int (NODE_T *, MP_T *, MP_T *, INT_T, int);
 338  extern MP_T *pow_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 339  extern MP_T *real_to_mp (NODE_T *, MP_T *, REAL_T, int);
 340  extern MP_T *rec_mp (NODE_T *, MP_T *, MP_T *, int);
 341  extern MP_T *round_mp (NODE_T *, MP_T *, MP_T *, int);
 342  extern MP_T *sec_mp (NODE_T *, MP_T *, MP_T *, int);
 343  extern MP_T *set_mp (MP_T *, MP_T, INT_T, int);
 344  extern MP_T *shorten_mp (NODE_T *, MP_T *, int, MP_T *, int);
 345  extern MP_T *sindg_mp (NODE_T *, MP_T *, MP_T *, int);
 346  extern MP_T *sinh_mp (NODE_T *, MP_T *, MP_T *, int);
 347  extern MP_T *sin_mp (NODE_T *, MP_T *, MP_T *, int);
 348  extern MP_T *sinpi_mp (NODE_T *, MP_T *, MP_T *, int);
 349  extern MP_T *sqrt_mp (NODE_T *, MP_T *, MP_T *, int);
 350  extern MP_T *strtomp (NODE_T *, MP_T *, char *, int);
 351  extern MP_T *sub_mp (NODE_T *, MP_T *, MP_T *, MP_T *, int);
 352  extern MP_T *tandg_mp (NODE_T *, MP_T *, MP_T *, int);
 353  extern MP_T *tanh_mp (NODE_T *, MP_T *, MP_T *, int);
 354  extern MP_T *tan_mp (NODE_T *, MP_T *, MP_T *, int);
 355  extern MP_T *tanpi_mp (NODE_T *, MP_T *, MP_T *, int);
 356  extern MP_T *tenth_mp (NODE_T *, MP_T *, MP_T *, int);
 357  extern MP_T *trunc_mp (NODE_T *, MP_T *, MP_T *, int);
 358  extern MP_T *unt_to_mp (NODE_T *, MP_T *, UNSIGNED_T, int);
 359  extern REAL_T mp_to_real (NODE_T *, MP_T *, int);
 360  extern void eq_mp (NODE_T *, A68_BOOL *, MP_T *, MP_T *, int);
 361  extern void ge_mp (NODE_T *, A68_BOOL *, MP_T *, MP_T *, int);
 362  extern void genie_pi_mp (NODE_T *);
 363  extern void gt_mp (NODE_T *, A68_BOOL *, MP_T *, MP_T *, int);
 364  extern void le_mp (NODE_T *, A68_BOOL *, MP_T *, MP_T *, int);
 365  extern void lt_mp (NODE_T *, A68_BOOL *, MP_T *, MP_T *, int);
 366  extern void ne_mp (NODE_T *, A68_BOOL *, MP_T *, MP_T *, int);
 367  extern void raw_write_mp (char *, MP_T *, int);
 368  extern void set_long_mp_digits (int);
 369  extern void test_mp_int_range (NODE_T *, MP_T *, MOID_T *);
 370  
 371  extern GPROC genie_infinity_mp;
 372  extern GPROC genie_minus_infinity_mp;
 373  extern GPROC genie_beta_inc_mp;
 374  extern GPROC genie_gamma_inc_mp;
 375  extern GPROC genie_gamma_inc_f_mp;
 376  extern GPROC genie_gamma_inc_g_mp;
 377  extern GPROC genie_gamma_inc_h_mp;
 378  extern GPROC genie_gamma_inc_gf_mp;
 379  extern GPROC genie_abs_mp;
 380  extern GPROC genie_abs_mp_complex;
 381  extern GPROC genie_acosdg_mp;
 382  extern GPROC genie_acosdg_mp;
 383  extern GPROC genie_acosh_mp;
 384  extern GPROC genie_acosh_mp_complex;
 385  extern GPROC genie_acos_mp;
 386  extern GPROC genie_acos_mp_complex;
 387  extern GPROC genie_acotdg_mp;
 388  extern GPROC genie_acot_mp;
 389  extern GPROC genie_asec_mp;
 390  extern GPROC genie_acsc_mp;
 391  extern GPROC genie_add_mp;
 392  extern GPROC genie_add_mp_complex;
 393  extern GPROC genie_and_mp;
 394  extern GPROC genie_arg_mp_complex;
 395  extern GPROC genie_asindg_mp;
 396  extern GPROC genie_asindg_mp;
 397  extern GPROC genie_asinh_mp;
 398  extern GPROC genie_asinh_mp_complex;
 399  extern GPROC genie_asin_mp;
 400  extern GPROC genie_asin_mp_complex;
 401  extern GPROC genie_atan2_mp;
 402  extern GPROC genie_atandg_mp;
 403  extern GPROC genie_atan2dg_mp;
 404  extern GPROC genie_atanh_mp;
 405  extern GPROC genie_atanh_mp_complex;
 406  extern GPROC genie_atan_mp;
 407  extern GPROC genie_atan_mp_complex;
 408  extern GPROC genie_bin_mp;
 409  extern GPROC genie_clear_long_mp_bits;
 410  extern GPROC genie_conj_mp_complex;
 411  extern GPROC genie_cosdg_mp;
 412  extern GPROC genie_cosh_mp;
 413  extern GPROC genie_cosh_mp_complex;
 414  extern GPROC genie_cos_mp;
 415  extern GPROC genie_cos_mp_complex;
 416  extern GPROC genie_cospi_mp;
 417  extern GPROC genie_cotdg_mp;
 418  extern GPROC genie_cot_mp;
 419  extern GPROC genie_sec_mp;
 420  extern GPROC genie_csc_mp;
 421  extern GPROC genie_cotpi_mp;
 422  extern GPROC genie_curt_mp;
 423  extern GPROC genie_divab_mp;
 424  extern GPROC genie_divab_mp_complex;
 425  extern GPROC genie_div_mp;
 426  extern GPROC genie_div_mp_complex;
 427  extern GPROC genie_elem_long_mp_bits;
 428  extern GPROC genie_elem_long_mp_bits;
 429  extern GPROC genie_entier_mp;
 430  extern GPROC genie_eq_mp;
 431  extern GPROC genie_eq_mp_complex;
 432  extern GPROC genie_erfc_mp;
 433  extern GPROC genie_erf_mp;
 434  extern GPROC genie_exp_mp;
 435  extern GPROC genie_exp_mp_complex;
 436  extern GPROC genie_gamma_mp;
 437  extern GPROC genie_lngamma_mp;
 438  extern GPROC genie_beta_mp;
 439  extern GPROC genie_lnbeta_mp;
 440  extern GPROC genie_ge_mp;
 441  extern GPROC genie_get_long_mp_bits;
 442  extern GPROC genie_get_long_mp_complex;
 443  extern GPROC genie_get_long_mp_int;
 444  extern GPROC genie_get_long_mp_real;
 445  extern GPROC genie_get_mp_complex;
 446  extern GPROC genie_gt_mp;
 447  extern GPROC genie_im_mp_complex;
 448  extern GPROC genie_inverfc_mp;
 449  extern GPROC genie_inverf_mp;
 450  extern GPROC genie_le_mp;
 451  extern GPROC genie_lengthen_complex_to_mp_complex;
 452  extern GPROC genie_lengthen_int_to_mp;
 453  extern GPROC genie_lengthen_mp_complex_to_long_mp_complex;
 454  extern GPROC genie_lengthen_mp_to_long_mp;
 455  extern GPROC genie_lengthen_real_to_mp;
 456  extern GPROC genie_lengthen_unt_to_mp;
 457  extern GPROC genie_ln_mp;
 458  extern GPROC genie_ln_mp_complex;
 459  extern GPROC genie_log_mp;
 460  extern GPROC genie_long_mp_bits_width;
 461  extern GPROC genie_long_mp_exp_width;
 462  extern GPROC genie_long_mp_int_width;
 463  extern GPROC genie_long_mp_max_bits;
 464  extern GPROC genie_long_mp_max_int;
 465  extern GPROC genie_long_mp_max_real;
 466  extern GPROC genie_long_mp_min_real;
 467  extern GPROC genie_long_mp_real_width;
 468  extern GPROC genie_long_mp_small_real;
 469  extern GPROC genie_lt_mp;
 470  extern GPROC genie_minusab_mp;
 471  extern GPROC genie_minusab_mp_complex;
 472  extern GPROC genie_minus_mp;
 473  extern GPROC genie_minus_mp_complex;
 474  extern GPROC genie_modab_mp;
 475  extern GPROC genie_mod_mp;
 476  extern GPROC genie_mul_mp;
 477  extern GPROC genie_mul_mp_complex;
 478  extern GPROC genie_ne_mp;
 479  extern GPROC genie_ne_mp_complex;
 480  extern GPROC genie_not_mp;
 481  extern GPROC genie_odd_mp;
 482  extern GPROC genie_or_mp;
 483  extern GPROC genie_overab_mp;
 484  extern GPROC genie_over_mp;
 485  extern GPROC genie_pi_mp;
 486  extern GPROC genie_plusab_mp;
 487  extern GPROC genie_plusab_mp_complex;
 488  extern GPROC genie_pow_mp;
 489  extern GPROC genie_pow_mp_complex_int;
 490  extern GPROC genie_pow_mp_int;
 491  extern GPROC genie_pow_mp_int_int;
 492  extern GPROC genie_print_long_mp_bits;
 493  extern GPROC genie_print_long_mp_complex;
 494  extern GPROC genie_print_long_mp_int;
 495  extern GPROC genie_print_long_mp_real;
 496  extern GPROC genie_print_mp_complex;
 497  extern GPROC genie_put_long_mp_bits;
 498  extern GPROC genie_put_long_mp_complex;
 499  extern GPROC genie_put_long_mp_int;
 500  extern GPROC genie_put_long_mp_real;
 501  extern GPROC genie_put_mp_complex;
 502  extern GPROC genie_read_long_mp_bits;
 503  extern GPROC genie_read_long_mp_complex;
 504  extern GPROC genie_read_long_mp_int;
 505  extern GPROC genie_read_long_mp_real;
 506  extern GPROC genie_read_mp_complex;
 507  extern GPROC genie_re_mp_complex;
 508  extern GPROC genie_round_mp;
 509  extern GPROC genie_set_long_mp_bits;
 510  extern GPROC genie_shl_mp;
 511  extern GPROC genie_shorten_long_mp_complex_to_mp_complex;
 512  extern GPROC genie_shorten_long_mp_to_mp;
 513  extern GPROC genie_shorten_mp_complex_to_complex;
 514  extern GPROC genie_shorten_mp_to_bits;
 515  extern GPROC genie_shorten_mp_to_int;
 516  extern GPROC genie_shorten_mp_to_real;
 517  extern GPROC genie_shr_mp;
 518  extern GPROC genie_sign_mp;
 519  extern GPROC genie_sindg_mp;
 520  extern GPROC genie_sinh_mp;
 521  extern GPROC genie_sinh_mp_complex;
 522  extern GPROC genie_sin_mp;
 523  extern GPROC genie_sin_mp_complex;
 524  extern GPROC genie_sinpi_mp;
 525  extern GPROC genie_sqrt_mp;
 526  extern GPROC genie_sqrt_mp_complex;
 527  extern GPROC genie_sub_mp;
 528  extern GPROC genie_sub_mp_complex;
 529  extern GPROC genie_tandg_mp;
 530  extern GPROC genie_tanh_mp;
 531  extern GPROC genie_tanh_mp_complex;
 532  extern GPROC genie_tan_mp;
 533  extern GPROC genie_tan_mp_complex;
 534  extern GPROC genie_tanpi_mp;
 535  extern GPROC genie_timesab_mp;
 536  extern GPROC genie_timesab_mp_complex;
 537  extern GPROC genie_xor_mp;
 538  
 539  #if defined (HAVE_GNU_MPFR)
 540  extern GPROC genie_beta_inc_mpfr;
 541  extern GPROC genie_ln_beta_mpfr;
 542  extern GPROC genie_beta_mpfr;
 543  extern GPROC genie_gamma_inc_mpfr;
 544  extern GPROC genie_gamma_inc_real_mpfr;
 545  extern GPROC genie_gamma_inc_double_real_mpfr;
 546  extern GPROC genie_gamma_mpfr;
 547  extern GPROC genie_lngamma_mpfr;
 548  extern GPROC genie_mpfr_erfc_mp;
 549  extern GPROC genie_mpfr_erf_mp;
 550  extern GPROC genie_mpfr_inverfc_mp;
 551  extern GPROC genie_mpfr_inverf_mp;
 552  extern GPROC genie_mpfr_mp;
 553  extern size_t mpfr_digits (void);
 554  #endif
 555  
 556  #if (A68_LEVEL >= 3)
 557  extern GPROC genie_quad_mp;
 558  #endif
 559  
 560  #if (A68_LEVEL <= 2)
 561  extern int get_mp_bits_width (MOID_T *);
 562  extern int get_mp_bits_words (MOID_T *);
 563  extern MP_BITS_T *stack_mp_bits (NODE_T *, MP_T *, MOID_T *);
 564  #endif
 565  
 566  #endif