acoshf.c
1 /* 2 * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without modification, 5 * are permitted provided that the following conditions are met: 6 * 1. Redistributions of source code must retain the above copyright notice, 7 * this list of conditions and the following disclaimer. 8 * 2. Redistributions in binary form must reproduce the above copyright notice, 9 * this list of conditions and the following disclaimer in the documentation 10 * and/or other materials provided with the distribution. 11 * 3. Neither the name of the copyright holder nor the names of its contributors 12 * may be used to endorse or promote products derived from this software without 13 * specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 21 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 * POSSIBILITY OF SUCH DAMAGE. 25 * 26 */ 27 28 #include "libm_amd.h" 29 #include "libm_util_amd.h" 30 #include "libm_special.h" 31 32 33 #undef _FUNCNAME 34 #define _FUNCNAME "acoshf" 35 float FN_PROTOTYPE_REF(acoshf)(float x) 36 { 37 38 unsigned int ux; 39 double dx, r, rarg, t; 40 41 static const unsigned int 42 recrteps = 0x46000000; /* 1/sqrt(eps) = 4.09600000000000000000e+03 */ 43 44 static const double 45 log2 = 6.93147180559945286227e-01; /* 0x3fe62e42fefa39ef */ 46 47 GET_BITS_SP32(x, ux); 48 49 if ((ux & EXPBITS_SP32) == EXPBITS_SP32) 50 { 51 /* x is either NaN or infinity */ 52 if (ux & MANTBITS_SP32) 53 { 54 /* x is NaN */ 55 #ifdef WINDOWS 56 return __amd_handle_errorf(_FUNCNAME,__amd_acosh, ux|0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F,1); 57 #else 58 if(ux & QNAN_MASK_32) 59 return __amd_handle_errorf(_FUNCNAME,__amd_acosh, ux|0x00400000, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0F,1); 60 else 61 return __amd_handle_errorf(_FUNCNAME,__amd_acosh, ux|0x00400000, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0F,1); 62 #endif 63 } 64 else 65 { 66 /* x is infinity */ 67 if (ux & SIGNBIT_SP32) 68 /* x is negative infinity. Return a NaN. */ 69 return __amd_handle_errorf(_FUNCNAME,__amd_acosh, INDEFBITPATT_SP32, _DOMAIN, 70 AMD_F_INVALID, EDOM, x, 0.0F,1); 71 else 72 /* Return positive infinity with no signal */ 73 return x; 74 } 75 } 76 else if ((ux & SIGNBIT_SP32) || (ux < 0x3f800000)) 77 { 78 /* x is less than 1.0. Return a NaN. */ 79 return __amd_handle_errorf(_FUNCNAME,__amd_acosh, INDEFBITPATT_SP32, _DOMAIN, 80 AMD_F_INVALID, EDOM, x, 0.0F,1); 81 } 82 83 dx = x; 84 85 if (ux > recrteps) 86 { 87 /* Arguments greater than 1/sqrt(epsilon) in magnitude are 88 approximated by acoshf(x) = ln(2) + ln(x) */ 89 r = FN_PROTOTYPE(log)(dx) + log2; 90 } 91 else if (ux > 0x40000000) 92 { 93 /* 2.0 <= x <= 1/sqrt(epsilon) */ 94 /* acoshf for these arguments is approximated by 95 acoshf(x) = ln(x + sqrt(x*x-1)) */ 96 rarg = dx*dx-1.0; 97 /* Use assembly instruction to compute r = sqrt(rarg); */ 98 ASMSQRT(rarg,r); 99 rarg = r + dx; 100 r = FN_PROTOTYPE(log)(rarg); 101 } 102 else 103 { 104 /* sqrt(epsilon) <= x <= 2.0 */ 105 t = dx - 1.0; 106 rarg = 2.0*t + t*t; 107 ASMSQRT(rarg,r); /* r = sqrt(rarg) */ 108 rarg = t + r; 109 r = FN_PROTOTYPE(log1p)(rarg); 110 } 111 return (float)(r); 112 } 113 114