25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER START
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * The contents of this file are subject to the terms of the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Common Development and Distribution License (the "License").
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You may not use this file except in compliance with the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * or http://www.opensolaris.org/os/licensing.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * See the License for the specific language governing permissions
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * and limitations under the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER END
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Use is subject to license terms.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
ddc0e0b53c661f6e439e3b7072b3ef353eadb4afRichard Lowe#pragma weak __powf = powf
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include "libm.h"
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include "xpg6.h" /* __xpg6 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define _C99SUSv3_pow _C99SUSv3_pow_treats_Inf_as_an_even_int
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#if defined(__i386) && !defined(__amd64)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisextern int __swapRP(int);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* INDENT OFF */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisstatic const double
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis ln2 = 6.93147180559945286227e-01, /* 0x3fe62e42, 0xfefa39ef */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dtwo = 2.0,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis done = 1.0,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dhalf = 0.5,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis d32 = 32.0,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis d1_32 = 0.03125,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis A0 = 1.999999999813723303647511146995966439250e+0000,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis A1 = 6.666910817935858533770138657139665608610e-0001,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t0 = 2.000000000004777489262405315073203746943e+0000,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t1 = 1.666663408349926379873111932994250726307e-0001;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisstatic const double S[] = {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.00000000000000000000e+00, /* 3FF0000000000000 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.02189714865411662714e+00, /* 3FF059B0D3158574 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.04427378242741375480e+00, /* 3FF0B5586CF9890F */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.06714040067682369717e+00, /* 3FF11301D0125B51 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.09050773266525768967e+00, /* 3FF172B83C7D517B */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.11438674259589243221e+00, /* 3FF1D4873168B9AA */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.13878863475669156458e+00, /* 3FF2387A6E756238 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.16372485877757747552e+00, /* 3FF29E9DF51FDEE1 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.18920711500272102690e+00, /* 3FF306FE0A31B715 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.21524735998046895524e+00, /* 3FF371A7373AA9CB */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.24185781207348400201e+00, /* 3FF3DEA64C123422 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.26905095719173321989e+00, /* 3FF44E086061892D */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.29683955465100964055e+00, /* 3FF4BFDAD5362A27 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.32523664315974132322e+00, /* 3FF5342B569D4F82 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.35425554693689265129e+00, /* 3FF5AB07DD485429 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.38390988196383202258e+00, /* 3FF6247EB03A5585 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.41421356237309514547e+00, /* 3FF6A09E667F3BCD */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.44518080697704665027e+00, /* 3FF71F75E8EC5F74 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.47682614593949934623e+00, /* 3FF7A11473EB0187 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.50916442759342284141e+00, /* 3FF82589994CCE13 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.54221082540794074411e+00, /* 3FF8ACE5422AA0DB */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.57598084510788649659e+00, /* 3FF93737B0CDC5E5 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.61049033194925428347e+00, /* 3FF9C49182A3F090 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.64575547815396494578e+00, /* 3FFA5503B23E255D */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.68179283050742900407e+00, /* 3FFAE89F995AD3AD */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.71861929812247793414e+00, /* 3FFB7F76F2FB5E47 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.75625216037329945351e+00, /* 3FFC199BDD85529C */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.79470907500310716820e+00, /* 3FFCB720DCEF9069 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.83400808640934243066e+00, /* 3FFD5818DCFBA487 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.87416763411029996256e+00, /* 3FFDFC97337B9B5F */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.91520656139714740007e+00, /* 3FFEA4AFA2A490DA */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.95714412417540017941e+00, /* 3FFF50765B6E4540 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis};
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisstatic const double TBL[] = {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 0.00000000000000000e+00,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 3.07716586667536873e-02,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 6.06246218164348399e-02,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 8.96121586896871380e-02,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.17783035656383456e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.45182009844497889e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.71850256926659228e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 1.97825743329919868e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 2.23143551314209765e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 2.47836163904581269e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 2.71933715483641758e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 2.95464212893835898e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 3.18453731118534589e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 3.40926586970593193e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 3.62905493689368475e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 3.84411698910332056e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 4.05465108108164385e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 4.26084395310900088e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 4.46287102628419530e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 4.66089729924599239e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 4.85507815781700824e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 5.04556010752395312e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 5.23248143764547868e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 5.41597282432744409e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 5.59615787935422659e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 5.77315365034823613e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 5.94707107746692776e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 6.11801541105992941e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 6.28608659422374094e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 6.45137961373584701e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 6.61398482245365016e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis 6.77398823591806143e-01,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis};
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisstatic const float zero = 0.0F, one = 1.0F, huge = 1.0e25f, tiny = 1.0e-25f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* INDENT ON */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisfloat
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtispowf(float x, float y) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis float fx = x, fy = y;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis float fz;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int ix, iy, jx, jy, k, iw, yisint;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis ix = *(int *)&x;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis iy = *(int *)&y;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis jx = ix & ~0x80000000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis jy = iy & ~0x80000000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (jy == 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (one); /* x**+-0 = 1 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else if (ix == 0x3f800000 && (__xpg6 & _C99SUSv3_pow) != 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (one); /* C99: 1**anything = 1 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else if (((0x7f800000 - jx) | (0x7f800000 - jy)) < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (fx * fy); /* at least one of x or y is NaN */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* includes Sun: 1**NaN = NaN */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* INDENT OFF */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * determine if y is an odd int
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * yisint = 0 ... y is not an integer
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * yisint = 1 ... y is an odd int
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * yisint = 2 ... y is an even int
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* INDENT ON */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis yisint = 0;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (ix < 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (jy >= 0x4b800000) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis yisint = 2; /* |y|>=2**24: y must be even */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else if (jy >= 0x3f800000) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis k = (jy >> 23) - 0x7f; /* exponent */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis iw = jy >> (23 - k);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((iw << (23 - k)) == jy)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis yisint = 2 - (iw & 1);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* special value of y */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((jy & ~0x7f800000) == 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (jy == 0x7f800000) { /* y is +-inf */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (jx == 0x3f800000) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((__xpg6 & _C99SUSv3_pow) != 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = one;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* C99: (-1)**+-inf is 1 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = fy - fy;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* Sun: (+-1)**+-inf = NaN */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else if (jx > 0x3f800000) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* (|x|>1)**+,-inf = inf,0 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (iy > 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = fy;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = zero;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else { /* (|x|<1)**-,+inf = inf,0 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (iy < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = -fy;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = zero;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (fz);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else if (jy == 0x3f800000) { /* y is +-1 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (iy < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fx = one / fx; /* y is -1 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (fx);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else if (iy == 0x40000000) { /* y is 2 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (fx * fx);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else if (iy == 0x3f000000) { /* y is 0.5 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (jx != 0 && jx != 0x7f800000)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (sqrtf(x));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* special value of x */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((jx & ~0x7f800000) == 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (jx == 0x7f800000 || jx == 0 || jx == 0x3f800000) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* x is +-0,+-inf,-1; set fz = |x|**y */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(int *)&fz = jx;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (iy < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = one / fz;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (ix < 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (jx == 0x3f800000 && yisint == 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* (-1)**non-int is NaN */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = zero;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz /= fz;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else if (yisint == 1) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* (x<0)**odd = -(|x|**odd) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = -fz;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (fz);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* (x<0)**(non-int) is NaN */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (ix < 0 && yisint == 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = zero;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (fz / fz);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * compute exp(y*log(|x|))
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * fx = *(float *) &jx;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * fz = (float) exp(((double) fy) * log((double) fx));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis double dx, dy, dz, ds;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int *px = (int *)&dx, *pz = (int *)&dz, i, n, m;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#if defined(__i386) && !defined(__amd64)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int rp = __swapRP(fp_extended);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fx = *(float *)&jx;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dx = (double)fx;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* compute log(x)/ln2 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis i = px[HIWORD] + 0x4000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis n = (i >> 20) - 0x3ff;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis pz[HIWORD] = i & 0xffff8000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis pz[LOWORD] = 0;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis ds = (dx - dz) / (dx + dz);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis i = (i >> 15) & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dz = ds * ds;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dy = invln2 * (TBL[i] + ds * (A0 + dz * A1));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (n == 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dz = (double)fy * dy;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dz = (double)fy * (dy + (double)n);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* compute exp2(dz=y*ln(x)) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis i = pz[HIWORD];
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((i & ~0x80000000) >= 0x40640000) { /* |z| >= 160.0 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = (i > 0)? huge : tiny;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (ix < 0 && yisint == 1)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz *= -fz; /* (-ve)**(odd int) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz *= fz;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#if defined(__i386) && !defined(__amd64)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (rp != fp_extended)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (void) __swapRP(rp);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (fz);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis n = (int)(d32 * dz + (i > 0 ? dhalf : -dhalf));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis i = n & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis m = n >> 5;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dy = ln2 * (dz - d1_32 * (double)n);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dx = S[i] * (done - (dtwo * dy) / (dy * (done - dy * t1) - t0));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (m != 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis px[HIWORD] += m << 20;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = (float)dx;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#if defined(__i386) && !defined(__amd64)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (rp != fp_extended)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (void) __swapRP(rp);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* end of computing exp(y*log(x)) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (ix < 0 && yisint == 1)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fz = -fz; /* (-ve)**(odd int) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (fz);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}