this repo has no description
at fixPythonPipStalling 260 lines 7.3 kB view raw
1/* 2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22// 23// d3ops.c 24// 25// Double-double Function Library 26// Copyright: � 1995-96 by Apple Computer, Inc., all rights reserved 27// 28// Triple-double precision basic operations. 29// 30// (high, mid, low) <-- (a, b, c) <op> (d, e, f) 31// where <op> is add, multiply, or divide 32// 33// void _d3div(double a, double b, double c, double d, double e, double f, 34// double *high, double *mid, double *low); 35// void _d3mul(double a, double b, double c, double d, double e, double f, 36// double *high, double *mid, double *low); 37// void _d3add(double a, double b, double c, double d, double e, double f, 38// double *high, double *mid, double *low); 39// 40 41#include "math.h" 42#include "fp_private.h" 43#if (__WANT_LONG_DOUBLE_FORMAT__ - 0L == 128L) 44#include "DD.h" 45 46static const hexdouble infinity = {{0x7ff00000, 0x00000000}}; 47static const hexdouble tiny = {{0x00100000, 0x00000000}}; 48 49 50void _d3div(double a, double b, double c, double d, double e, double f, 51 double *high, double *mid, double *low) 52{ 53 // (high, mid, low) <-- (a, b, c) / (d, e, f) 54 55 double p, q, r, s, t, u, v, w, x, y, z; 56 double g, h, o, rmid, rlow; 57 // int lx, l1, l2; 58 59 // lx = (fabs(d) < tiny.d); // look out for overflow on 1/d 60 p = 1.0/d; // reciprocal of h.o. denominator term 61 if (fabs(d) < tiny.d) { 62 r=a/d; // if quotient is infinity, 63 if (fabs(r)==infinity.d) { // stop process, and return 64 *high = r; 65 *mid = 0.0e0; 66 *low = 0.0e0; // properly signed infinity 67 return; 68 } 69 } 70 else { 71 q = a*p; 72 r = q + (a - q*d)*p; // h.o. quotient term 73 } 74 s = a - r*d; // exact remainder 75 t = __FMUL( r, e); // second order remainder term 76 // l1 = (fabs(b) > fabs(t)) 77 u = (r*e - t) + r*f; // third order remainder term 78 w = __FSUB( b, t ); // combine the 79 y = __FADD( s, w ); // second order terms 80 // l2 = (fabs(s) > fabs(w)); // and catch bits that may fall 81 82 if (fabs(b) > fabs(t)) // off the end to include in the 83 x = b - w - t; // third order term 84 else 85 x = b - (w + t); 86 if (fabs(s) > fabs(w)) 87 z = s - y + w; 88 else 89 z = w - y + s; 90 g = c - u + x + z; // third order term 91 if (fabs(d) < tiny.d) { // caution against tiny quotients, again 92 o = y/d; 93 v = (y - __FMUL( o, d ) + g - (e*o + (f*o))) / d; 94 } 95 else { 96 h = y*p; 97 o = h + (y - h*d)*p; // second order term 98 v = (y - o*d + g - (e*o + (f*o)))*p;// third order quotient term 99 } 100 rmid = o + v; // start distillation of quotient 101 rlow = o - rmid + v; 102 103 *high = __FADD( r, rmid ); 104 *mid = (r - *high + rmid) + rlow; 105 *low = (r - *high + rmid) - *mid + rlow; 106 107 return; 108} 109 110 111void _d3mul(double a, double b, double c, double d, double e, double f, 112 double *high, double *mid, double *low) 113{ 114 // (high, mid, low) <-- (a, b, c) * (d, e, f) 115 116 double s, t, u, v, w, x, y, z, tlow, resbump; 117 // int l1, l2; 118 119 u = d*c + e*b + f*a; // sextuple precision multiplication 120 v = __FMUL( d, b ); // derived from _q_mp10.c 121 w = d*b - v; 122 x = __FMUL( e, a ); 123 y = e*a - x; 124 // l1=(fabs(x) > fabs(v)); 125 s = w + y + u; 126 z = __FMUL( d, a); 127 w = d*a - z; 128 u = __FADD( v, x ); 129 // l2=(fabs(w) > fabs(u)); 130 if (fabs(x) > fabs(v)) 131 s = x - u + v + s; 132 else 133 s = v - u + x + s; 134 t = __FADD( u, w ); 135 if (fabs(w) > fabs(u)) 136 tlow = w - t + u + s; 137 else 138 tlow = u - t + w + s; 139 resbump = __FADD( t, tlow ); 140 tlow = t - resbump + tlow; 141 142 *high = __FADD( z, resbump ); 143 *mid = (z - *high + resbump) + tlow; 144 *low = (z - *high + resbump) - *mid + tlow; 145 146 return; 147} 148 149 150void _d3add(double a, double b, double c, double d, double e, double f, 151 double *high, double *mid, double *low) 152{ 153 // (high, mid, low) <-- (a, b, c) + (d, e, f) 154 155 // int l1, l2, l3, l4, l5, l5, l6, l7, l8; 156 double p, q, r, s, t, u, v, w, x, y, z; 157 double res, carry, z1, z2, resmid, reslow; 158 159 // l1=(fabs(a) > fabs(d)); 160 // l2=(fabs(b) > fabs(e)); 161 // l3=(fabs(c) > fabs(f)); 162 163 p = __FADD( a, d ); 164 q = __FADD( b, e ); 165 r = __FADD( c, f ); 166 167 if (fabs(a) > fabs(d)) // a b c 168 s = a - p + d; // d e f 169 else // p s (replaces a and d 170 s = d - p + a; 171 172 if (fabs(b) > fabs(e)) 173 t = b - q + e; // q t (replaces b and e 174 else 175 t = e - q + b; 176 177 // l4=(fabs(s) > fabs(q)); 178 // l5=(fabs(t) > fabs(r)); 179 180 if (fabs(c) > fabs(f)) 181 u = c - r + f; // r u (replaces c and f 182 else 183 u = f - r + c; 184 185 v = __FADD( s, q ); 186 x = __FADD( t, r ); 187 188 // l6=(fabs(p) > fabs(v)); 189 190 if (fabs(s) > fabs(q)) 191 w = s - v + q; // v w (replaces s and q 192 else 193 w = q - v + s; 194 195 // l7=(fabs(x) > fabs(w)); 196 197 if (fabs(t) > fabs(r)) 198 y = t - x + r; // x y (replaces t and r 199 else 200 y = r - x + t; 201 202 z = __FADD( x, w ); 203 res = __FADD( p, v ); 204 205 if (fabs(p) > fabs(v)) 206 carry = p - res + v; // res carry (replaces p and v 207 else 208 carry = v - res + p; 209 210 // l8=(fabs(carry) > fabs(z)); 211 212 if (fabs(x) > fabs(w)) 213 z1 = x - z + w; // z z1 (replaces x and w 214 else 215 z1 = w - z + x; 216 217 z2 = u + y + z1; // z2 (replaces u, y, and z1 218 resmid = __FADD( carry, z ); 219 220 if (fabs(carry) > fabs(z)) 221 reslow = carry - resmid + z; // resmid carry2 (replaces carry, z 222 else 223 reslow = z - resmid + carry; 224 225 *high = __FADD( res, resmid ); 226 *mid = (res - *high + resmid) + reslow; 227 *low = (res - *high + resmid) - *mid + reslow + z2; 228 229 return; 230} 231#endif 232#if 0 // set to 1 to include code for self-contained sanity test 233 234#include <stdio.h> 235 236main() 237{ 238 double a1,a2,a3, b1,b2,b3, c1,c2,c3, d1,d2,d3, e1,e2,e3; 239 240 _d3div( 2, 0, 0, 3, 0, 0, &a1, &a2, &a3); // a = 2/3 241 _d3div( 5, 0, 0, 7, 0, 0, &b1, &b2, &b3); // b = 5/7 242 _d3mul(a1, a2, a3, b1, b2, b3, &c1, &c2, &c3); // c = a*b = 10/21 243 _d3div(21, 0, 0, 10, 0, 0, &d1, &d2, &d3); // d = 21/10 244 _d3mul(c1, c2, c3, d1, d2, d3, &e1, &e2, &e3); // e = c*d (should be 1) 245 246 printf("e: %24.18e %24.18e %24.18e\n", e1, e2, e3); 247 248 _d3add(a1, a2, a3, b1, b2, b3, &c1, &c2, &c3); // c = a+b = 29/21 249 _d3div( 8, 0, 0, 21, 0, 0, &d1, &d2, &d3); // d = 8/21 250 _d3add(c1, c2, c3,-d1,-d2,-d3, &e1, &e2, &e3); // e = c-d (should be 1) 251 252 printf("e: %24.18e %24.18e %24.18e\n", e1, e2, e3); 253} 254 255// Correct test results: 256// 257// e: 1.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 258// e: 1.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 259 260#endif