1226458Sdas/*- 2226458Sdas * Copyright (c) 2011 David Schultz 3226458Sdas * All rights reserved. 4226458Sdas * 5226458Sdas * Redistribution and use in source and binary forms, with or without 6226458Sdas * modification, are permitted provided that the following conditions 7226458Sdas * are met: 8226458Sdas * 1. Redistributions of source code must retain the above copyright 9226458Sdas * notice unmodified, this list of conditions, and the following 10226458Sdas * disclaimer. 11226458Sdas * 2. Redistributions in binary form must reproduce the above copyright 12226458Sdas * notice, this list of conditions and the following disclaimer in the 13226458Sdas * documentation and/or other materials provided with the distribution. 14226458Sdas * 15226458Sdas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16226458Sdas * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17226458Sdas * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18226458Sdas * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19226458Sdas * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20226458Sdas * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21226458Sdas * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22226458Sdas * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23226458Sdas * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24226458Sdas * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25226458Sdas */ 26226458Sdas 27226458Sdas/* 28226458Sdas * Hyperbolic tangent of a complex argument z. See s_ctanh.c for details. 29226458Sdas */ 30226458Sdas 31226458Sdas#include <sys/cdefs.h> 32226458Sdas__FBSDID("$FreeBSD$"); 33226458Sdas 34226458Sdas#include <complex.h> 35226458Sdas#include <math.h> 36226458Sdas 37226458Sdas#include "math_private.h" 38226458Sdas 39226458Sdasfloat complex 40226458Sdasctanhf(float complex z) 41226458Sdas{ 42226458Sdas float x, y; 43226458Sdas float t, beta, s, rho, denom; 44226458Sdas uint32_t hx, ix; 45226458Sdas 46226458Sdas x = crealf(z); 47226458Sdas y = cimagf(z); 48226458Sdas 49226458Sdas GET_FLOAT_WORD(hx, x); 50226458Sdas ix = hx & 0x7fffffff; 51226458Sdas 52226458Sdas if (ix >= 0x7f800000) { 53226458Sdas if (ix & 0x7fffff) 54226458Sdas return (cpackf(x, (y == 0 ? y : x * y))); 55226458Sdas SET_FLOAT_WORD(x, hx - 0x40000000); 56226458Sdas return (cpackf(x, 57226458Sdas copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)))); 58226458Sdas } 59226458Sdas 60226600Sdas if (!isfinite(y)) 61226600Sdas return (cpackf(y - y, y - y)); 62226600Sdas 63226458Sdas if (ix >= 0x41300000) { /* x >= 11 */ 64226458Sdas float exp_mx = expf(-fabsf(x)); 65226458Sdas return (cpackf(copysignf(1, x), 66226458Sdas 4 * sinf(y) * cosf(y) * exp_mx * exp_mx)); 67226458Sdas } 68226458Sdas 69226458Sdas t = tanf(y); 70226458Sdas beta = 1.0 + t * t; 71226458Sdas s = sinhf(x); 72226458Sdas rho = sqrtf(1 + s * s); 73226458Sdas denom = 1 + beta * s * s; 74226458Sdas return (cpackf((beta * rho * s) / denom, t / denom)); 75226458Sdas} 76226458Sdas 77226458Sdasfloat complex 78226458Sdasctanf(float complex z) 79226458Sdas{ 80226458Sdas 81226458Sdas z = ctanhf(cpackf(-cimagf(z), crealf(z))); 82226458Sdas return (cpackf(cimagf(z), -crealf(z))); 83226458Sdas} 84226458Sdas 85