]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/ieee754/dbl-64/mpa.h
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / ieee754 / dbl-64 / mpa.h
index 59c58efadfe58879b810dd4f7a79eba102191c7d..bf1ad873d19af1792787eab92bcf9094048aede0 100644 (file)
@@ -1,58 +1,78 @@
-
 /*
  * IBM Accurate Mathematical Library
- * Copyright (c) International Business Machines Corp., 2001
+ * Written by International Business Machines Corp.
+ * Copyright (C) 2001-2014 Free Software Foundation, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or 
+ * the Free Software Foundation; either version 2.1 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
+
 /************************************************************************/
 /*  MODULE_NAME: mpa.h                                                  */
 /*                                                                      */
 /*  FUNCTIONS:                                                          */
 /*               mcr                                                    */
 /*               acr                                                    */
-/*               cr                                                     */
 /*               cpy                                                    */
-/*               cpymn                                                  */
 /*               mp_dbl                                                 */
 /*               dbl_mp                                                 */
 /*               add                                                    */
 /*               sub                                                    */
 /*               mul                                                    */
-/*               inv                                                    */
 /*               dvd                                                    */
 /*                                                                      */
 /* Arithmetic functions for multiple precision numbers.                 */
 /* Common types and definition                                          */
 /************************************************************************/
 
+#include <mpa-arch.h>
+
+/* The mp_no structure holds the details of a multi-precision floating point
+   number.
+
+   - The radix of the number (R) is 2 ^ 24.
+
+   - E: The exponent of the number.
+
+   - D[0]: The sign (-1, 1) or 0 if the value is 0.  In the latter case, the
+     values of the remaining members of the structure are ignored.
+
+   - D[1] - D[p]: The mantissa of the number where:
+
+       0 <= D[i] < R and
+       P is the precision of the number and 1 <= p <= 32
+
+     D[p+1] ... D[39] have no significance.
+
+   - The value of the number is:
+
+       D[1] * R ^ (E - 1) + D[2] * R ^ (E - 2) ... D[p] * R ^ (E - p)
 
-typedef struct {/* This structure holds the details of a multi-precision     */
-  int e;        /* floating point number, x: d[0] holds its sign (-1,0 or 1) */
-  double d[40]; /* e holds its exponent (...,-2,-1,0,1,2,...) and            */
-} mp_no;        /* d[1]...d[p] hold its mantissa digits. The value of x is,  */
-                /* x = d[1]*r**(e-1) + d[2]*r**(e-2) + ... + d[p]*r**(e-p).  */
-                /* Here   r = 2**24,   0 <= d[i] < r  and  1 <= p <= 32.     */
-                /* p is a global variable. A multi-precision number is       */
-                /* always normalized. Namely, d[1] > 0. An exception is      */
-                /* a zero which is characterized by d[0] = 0. The terms      */
-                /* d[p+1], d[p+2], ... of a none zero number have no         */
-                /* significance and so are the terms e, d[1],d[2],...        */
-                /* of a zero.                                                */
+   */
+typedef struct
+{
+  int e;
+  mantissa_t d[40];
+} mp_no;
 
-typedef union { int i[2]; double d; } number;
+typedef union
+{
+  int i[2];
+  double d;
+} number;
+
+extern const mp_no mpone;
+extern const mp_no mptwo;
 
 #define  X   x->d
 #define  Y   y->d
@@ -61,19 +81,76 @@ typedef union { int i[2]; double d; } number;
 #define  EY  y->e
 #define  EZ  z->e
 
-#define MAX(x,y) ((x) < (y) ?  (y) : (x))
-#define MIN(x,y) ((x) < (y) ?  (x) : (y))
 #define ABS(x)   ((x) <  0  ? -(x) : (x))
 
-int acr(const mp_no *, const mp_no *, int);
-int  cr(const mp_no *, const mp_no *, int);
-void cpy(const mp_no *, mp_no *, int);
-void cpymn(const mp_no *, int, mp_no *, int);
-void mp_dbl(const mp_no *, double *, int);
-void dbl_mp(double, mp_no *, int);
-void add(const mp_no *, const mp_no *, mp_no *, int);
-void sub(const mp_no *, const mp_no *, mp_no *, int);
-void mul(const mp_no *, const mp_no *, mp_no *, int);
-void inv(const mp_no *, mp_no *, int);
-void dvd(const mp_no *, const mp_no *, mp_no *, int);
+#ifndef RADIXI
+# define  RADIXI    0x1.0p-24          /* 2^-24   */
+#endif
+
+#ifndef TWO52
+# define  TWO52     0x1.0p52           /* 2^52    */
+#endif
+
+#define  TWO5      TWOPOW (5)          /* 2^5     */
+#define  TWO8      TWOPOW (8)          /* 2^52    */
+#define  TWO10     TWOPOW (10)         /* 2^10    */
+#define  TWO18     TWOPOW (18)         /* 2^18    */
+#define  TWO19     TWOPOW (19)         /* 2^19    */
+#define  TWO23     TWOPOW (23)         /* 2^23    */
+
+#define  HALFRAD   TWO23
+
+#define  TWO57     0x1.0p57            /* 2^57    */
+#define  TWO71     0x1.0p71            /* 2^71    */
+#define  TWOM1032  0x1.0p-1032         /* 2^-1032 */
+#define  TWOM1022  0x1.0p-1022         /* 2^-1022 */
+
+#define  HALF      0x1.0p-1            /* 1/2 */
+#define  MHALF     -0x1.0p-1           /* -1/2 */
+
+int __acr (const mp_no *, const mp_no *, int);
+void __cpy (const mp_no *, mp_no *, int);
+void __mp_dbl (const mp_no *, double *, int);
+void __dbl_mp (double, mp_no *, int);
+void __add (const mp_no *, const mp_no *, mp_no *, int);
+void __sub (const mp_no *, const mp_no *, mp_no *, int);
+void __mul (const mp_no *, const mp_no *, mp_no *, int);
+void __sqr (const mp_no *, mp_no *, int);
+void __dvd (const mp_no *, const mp_no *, mp_no *, int);
+
+extern void __mpatan (mp_no *, mp_no *, int);
+extern void __mpatan2 (mp_no *, mp_no *, mp_no *, int);
+extern void __mpsqrt (mp_no *, mp_no *, int);
+extern void __mpexp (mp_no *, mp_no *, int);
+extern void __c32 (mp_no *, mp_no *, mp_no *, int);
+extern int __mpranred (double, mp_no *, int);
+
+/* Given a power POW, build a multiprecision number 2^POW.  */
+static inline void
+__pow_mp (int pow, mp_no *y, int p)
+{
+  int i, rem;
+
+  /* The exponent is E such that E is a factor of 2^24.  The remainder (of the
+     form 2^x) goes entirely into the first digit of the mantissa as it is
+     always less than 2^24.  */
+  EY = pow / 24;
+  rem = pow - EY * 24;
+  EY++;
+
+  /* If the remainder is negative, it means that POW was negative since
+     |EY * 24| <= |pow|.  Adjust so that REM is positive and still less than
+     24 because of which, the mantissa digit is less than 2^24.  */
+  if (rem < 0)
+    {
+      EY--;
+      rem += 24;
+    }
+  /* The sign of any 2^x is always positive.  */
+  Y[0] = 1;
+  Y[1] = 1 << rem;
 
+  /* Everything else is 0.  */
+  for (i = 2; i <= p; i++)
+    Y[i] = 0;
+}