this repo has no description
at fixPythonPipStalling 223 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// PowerDD.c 24// 25// Double-double Function Library 26// Copyright: � 1995-96 by Apple Computer, Inc., all rights reserved 27// 28// long double powl( long double base, long double exponent ); 29// 30 31#include "math.h" 32#include "fp_private.h" 33#if (__WANT_LONG_DOUBLE_FORMAT__ - 0L == 128L) 34#include "DD.h" 35 36extern long double rintl(long double); 37 38 39// Floating-point constants 40 41static const Double kInfinityu = {{0x7ff00000,0x0}}; 42 43long double _ExpInnerLD(double, double, double, double *, int); 44long double _LogInnerLD(double, double, double, double *, int); 45static long double PowerInnerLD(double, double, double, double); 46 47long double powl( long double base, long double exponent ) 48{ 49 DblDbl u, v; 50 double basehi, baselo, exphi, explo; 51 int isExpOddInt; 52 uint32_t expExp; 53 double fpenv; 54 long double ldTemp; 55 56 u.f = base; 57 basehi = u.d[0]; 58 baselo = u.d[1]; 59 v.f = exponent; 60 exphi = v.d[0]; 61 explo = v.d[1]; 62 63 if (((v.i[0] & 0x000fffffu) | v.i[1] | (v.i[2] & 0x7fffffffu) | v.i[3]) == 0) { 64 expExp = v.i[0] & 0xfff00000u; 65 if (expExp == 0x40000000) return base*base; // if exponent == 2.0 66 else if (exponent == 0.0) return 1.0; // if exponent == 0.0 67 else if (expExp == 0x3ff00000) return base; // if exponent == 1.0 68 else if (expExp == 0xbff00000) return 1.0/base; // if exponent == -1.0 69 } 70 71 FEGETENVD(fpenv); 72 FESETENVD(0.0); 73 74 if ((v.i[0] & 0x7ff00000u) < 0x7ff00000u) { // exponent is finite 75 if ((u.i[0] & 0x7ff00000u) < 0x7ff00000u) { // base is finite 76 if (basehi > 0.0) { // base positive 77 ldTemp = PowerInnerLD(basehi, baselo, exphi, explo); 78 FESETENVD(fpenv); 79 return ldTemp; 80 } 81 if (basehi < 0.0) { // base negative 82 if (rintl(exponent) != exponent) { // exponent is non-integer 83 u.d[0] = NAN; 84 u.d[1] = 0.0; 85 FESETENVD(fpenv); 86 return u.f; 87 } 88 u.f = PowerInnerLD(-basehi, -baselo, exphi, explo); 89 if (rintl(0.5*exponent) != 0.5*exponent) // exponent is odd 90 u.f = -u.f; 91 FESETENVD(fpenv); 92 return u.f; 93 } 94 else { // base is 0.0: 95 isExpOddInt = ((rintl(exponent) == exponent) ? 96 (rintl(0.5*exponent) != 0.5*exponent) : 0); 97 if (exphi > 0.0) { 98 ldTemp = (isExpOddInt) ? base : 0.0; 99 FESETENVD(fpenv); 100 return ldTemp; 101 } 102 else { // exponent < 0.0 103 u.d[0] = (isExpOddInt) ? 1.0/basehi : 1.0/fabs(basehi); 104 u.d[1] = 0.0; 105 FESETENVD(fpenv); 106 return u.f; 107 } 108 } 109 } // Exponent is finite, Base is not. 110 else if (basehi != basehi) // Base is NaN, return NaN 111 return base; 112 else // base is +-Inf 113 { 114 if (basehi > 0.0) // base is +inf 115 { 116 if (exphi > 0.0) // pow(+inf, >0) 117 return (long double) INFINITY; 118 else // pow(+inf, <0) 119 return 0.0L; 120 } 121 else // base is -inf 122 { 123 // If exponent is an integer, and exponent/2 is not, then exponent is an odd integer. 124 isExpOddInt = ((rintl(exponent) == exponent) && (rintl(0.5*exponent) != 0.5*exponent)); 125 if (exphi > 0.0) { 126 // previously signs were incorrect in this expression; we should be returning 127 // -Inf when the exponent is an odd integer, +Inf otherwise. 128 ldTemp = (isExpOddInt) ? (long double) -INFINITY : (long double) INFINITY; 129 FESETENVD(fpenv); 130 return ldTemp; 131 } 132 else { // exponent < 0.0 133 // Return -0 if exponent is an odd integer, +0 otherwise. 134 u.d[0] = (isExpOddInt) ? -0.0 : 0.0; 135 u.d[1] = 0.0; 136 FESETENVD(fpenv); 137 return u.f; 138 } 139 } 140 } 141 } 142 else if (exphi != exphi) // Exponent is a NaN 143 { 144 if (base == 1.0L) 145 return base; 146 else 147 return base + exponent; 148 } 149 else // exponent is +-Inf 150 { 151 if (basehi != basehi) 152 return base; 153 154 ldTemp = fabsl(base); 155 if ( (exphi > 0.0 && ldTemp > 1.0L) || (exphi < 0.0 && ldTemp < 1.0L) ) 156 return (long double) INFINITY; 157 else if ( (exphi > 0.0 && ldTemp < 1.0L) || (exphi < 0.0 && ldTemp > 1.0L) ) 158 return 0.0L; 159 else 160 return 1.0L; 161 } 162} 163 164//*************************************************************************** 165// 166// FUNCTION: static long double PowerInnerLD(double alpha, double beta, 167// double beta, double gamma); 168// 169// DESCRIPTION: Computes the base to the exponent power where: alpha/beta 170// are the head/tail of base, and gamma/delta are head/tail 171// of exponent . This routine is called internally by the 172// long double Power function family. It assumes that 173// base is finite and > 0, exponent is finite. 174// 175//***************************************************************************/ 176 177static long double PowerInnerLD(double alpha, double beta, double gamma, double delta) 178{ 179 DblDbl u; 180 double extra, ahi, amid, amid2, alow, amid3; 181 double amid4, ahi1, amid5, amid6, ahi2, amid7, amid8; 182 183 u.f = _LogInnerLD(alpha, beta, 0.0, &extra, 1); 184 ahi = __FMUL( u.d[0], gamma ); 185 amid = __FMSUB( u.d[0], gamma, ahi ); // u.d[0] * gamma - ahi; 186 amid2 = __FMUL( u.d[1], gamma ); 187 alow = __FMADD( gamma, extra, __FMSUB( u.d[1], gamma, amid2 ) ); // u.d[1] * gamma - amid2 + gamma * extra; 188 amid3 = __FMUL( u.d[0], delta ); 189 alow = __FMADD( delta, u.d[1], __FMSUB( u.d[0], delta, amid3) + alow ); // u.d[0] * delta - amid3 + alow + delta * u.d[1]; 190 amid4 = __FADD( amid, amid2 ); 191 ahi1 = __FADD( ahi, amid4 ); 192 amid5 = ahi - ahi1 + amid4; 193 if (fabs(amid) > fabs(amid2)) 194 alow = amid - amid4 + amid2 + alow; 195 else 196 alow = amid2 - amid4 + amid + alow; 197 amid6 = __FADD( amid3, amid5 ); 198 ahi2 = __FADD( ahi1, amid6 ); 199 if (fabs(amid3) > fabs(amid5)) 200 alow = amid3 - amid6 + amid5 + alow; 201 else 202 alow = amid5 - amid6 + amid3 + alow; 203 amid7 = ahi1 - ahi2 + amid6; 204 amid8 = __FADD( amid7, alow ); 205 alow = amid7 - amid8 + alow; 206 if (fabs(ahi) == kInfinityu.f) { 207 if (ahi > 0.0) { 208 u.d[0] = kInfinityu.f; 209 u.d[1] = 0.0; 210 } 211 else { 212 u.d[0] = 0.0; 213 u.d[1] = 0.0; 214 } 215 } 216 else { 217 u.f = _ExpInnerLD(ahi2, amid8, alow, &extra, 3); 218 if ((u.i[0] & 0x7ff00000) == 0x7ff00000) 219 u.d[1] = 0.0; 220 } 221 return u.f; 222} 223#endif