this repo has no description
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#include "math.h"
24#include "fenv.h"
25#include "fp_private.h"
26#include "fenv_private.h"
27
28float acosf( float x ) { return (float)acos((double)( x )); }
29float asinf( float x ) { return (float)asin((double)( x )); }
30float atanf( float x ) { return (float)atan( (double)x ); }
31float atan2f( float y, float x) { return (float)atan2( (double)y, (double)x ); }
32float cosf( float x ) { return (float)cos((double)( x )); }
33float sinf( float x) { return (float)sin( (double)x ); }
34float tanf( float x ) { return (float)tan( (double)x ); }
35float acoshf( float x ) { return (float)acosh( (double)x ); }
36float asinhf( float x ) { return (float)asinh( (double)x ); }
37float atanhf( float x ) { return (float)atanh( (double)x ); }
38float coshf( float x) { return (float)cosh( (double)x ); }
39float sinhf( float x) { return (float)sinh( (double)x ); }
40float tanhf( float x) { return (float)tanh( (double)x ); }
41
42float expf( float x) { return (float)exp( (double)x ); }
43float exp2f( float x) { return (float)exp2( (double)x ); }
44float expm1f( float x ) { return (float)expm1( (double)x ); }
45float logf ( float x ) { return (float)log( (double)x ); }
46float log10f ( float x ) { return (float)log10( (double)x ); }
47float log2f ( float x ) { return (float)log2( x ); }
48float log1pf ( float x ) { return (float)log1p( (double)x ); }
49
50float cbrtf( float x ) { return (float)cbrt((double)( x )); }
51float powf ( float x, float y ) { return (float)pow ( (double)x, (double)y ); }
52
53float erff( float x ) { return (float)erf((double)( x )); }
54float erfcf( float x ) { return (float)erfc((double)( x )); }
55float lgammaf( float x ) { return (float)lgamma((double)( x )); }
56float tgammaf( float x ) { return (float)tgamma((double)( x )); }
57
58 /* By calling through the double sqrt, we let the 970 hardware have a crack at this. */
59float sqrtf ( float x ) { return (float) sqrt((double) x); }
60
61static const hexsingle HugeF = { 0x7F800000 };
62static const hexsingle NegHugeF = { 0xFF800000 };
63
64float hypotf ( float x, float y )
65{
66 register float temp;
67 hexdouble OldEnvironment, CurrentEnvironment;
68
69 register float FPR_z, FPR_one, FPR_inf, FPR_Minf, FPR_absx, FPR_absy, FPR_big, FPR_small;
70 register double FPR_env;
71
72 FPR_z = 0.0f; FPR_one = 1.0f;
73 FPR_inf = HugeF.fval; FPR_Minf = NegHugeF.fval;
74 FPR_absx = __FABSF( x ); FPR_absy = __FABSF( y );
75
76/*******************************************************************************
77* If argument is SNaN then a QNaN has to be returned and the invalid *
78* flag signaled. *
79*******************************************************************************/
80
81 if (unlikely( ( x == FPR_inf ) || ( y == FPR_inf ) || ( x == FPR_Minf ) || ( y == FPR_Minf ) ))
82 return FPR_inf;
83
84 if (unlikely( ( x != x ) || ( y != y ) ))
85 {
86 x = __FABSF ( x + y );
87 return x;
88 }
89
90 if ( FPR_absx > FPR_absy )
91 {
92 FPR_big = FPR_absx;
93 FPR_small = FPR_absy;
94 }
95 else
96 {
97 FPR_big = FPR_absy;
98 FPR_small = FPR_absx;
99 }
100
101 // Now +0.0 <= FPR_small <= FPR_big < INFINITY
102
103 if (unlikely( FPR_small == FPR_z ))
104 return FPR_big;
105
106 FEGETENVD( FPR_env ); // save environment, set default
107 FESETENVD( FPR_z );
108
109 temp = FPR_small / FPR_big; OldEnvironment.d = FPR_env;
110 temp = sqrtf ( FPR_one + temp * temp );
111
112 FEGETENVD_GRP( CurrentEnvironment.d );
113 CurrentEnvironment.i.lo &= ~FE_UNDERFLOW; // Clear any inconsequential underflow
114 FESETENVD_GRP( CurrentEnvironment.d );
115
116 temp = FPR_big * temp; // Might raise UNDERFLOW or OVERFLOW
117
118 FEGETENVD_GRP( CurrentEnvironment.d );
119 OldEnvironment.i.lo |= CurrentEnvironment.i.lo; // Pick up any UF or OF
120 FESETENVD_GRP( OldEnvironment.d ); // restore caller's environment
121
122 return temp;
123}
124