3 #if defined(__MINGW32__) && A_PREREQ_GNUC(3, 0)
4 #pragma GCC diagnostic ignored "-Wfloat-conversion"
5 #endif /* __MINGW32__ */
6 #if A_PREREQ_GNUC(3, 0) || __has_warning("-Wfloat-equal")
7 #pragma GCC diagnostic ignored "-Wfloat-equal"
8 #endif /* -Wfloat-equal */
10 static A_INLINE a_float
polevl(a_float
const *p
, a_size n
, a_float x
)
19 a_f32
a_f32_rsqrt(a_f32 x
)
22 return 1 / a_f32_sqrt(x
);
32 a_f32 xh
= A_F32_C(0.5) * x
;
33 u
.u
= A_U32_C(0x5F375A86) - (u
.u
>> 1);
34 u
.x
*= A_F32_C(1.5) - u
.x
* u
.x
* xh
;
35 u
.x
*= A_F32_C(1.5) - u
.x
* u
.x
* xh
;
49 a_f64
a_f64_rsqrt(a_f64 x
)
52 return 1 / a_f64_sqrt(x
);
62 a_f64 xh
= A_F64_C(0.5) * x
;
63 u
.u
= A_U64_C(0x5FE6EC85E7DE30DA) - (u
.u
>> 1);
64 u
.x
*= A_F64_C(1.5) - u
.x
* u
.x
* xh
;
65 u
.x
*= A_F64_C(1.5) - u
.x
* u
.x
* xh
;
79 #if (__has_builtin(__builtin_clz) || A_PREREQ_GNUC(3, 4)) && (ULONG_MAX == A_U32_MAX)
80 #define A_U32_BSR(x) (31 - __builtin_clzl(x))
81 #elif __has_builtin(__builtin_clz) || A_PREREQ_GNUC(3, 4)
82 #define A_U32_BSR(x) (31 - __builtin_clz(x))
83 #elif defined(_MSC_VER)
84 #pragma intrinsic(_BitScanReverse)
85 #define A_U32_BSR(x) BitScanReverse(x)
86 static A_INLINE
int A_U32_BSR(a_u32 x
)
89 _BitScanReverse(&i
, x
);
92 #endif /* A_U32_BSR */
94 a_u16
a_u32_sqrt(a_u32 x
)
96 #if defined(A_U32_BSR) /* Newton's method */
98 if (x
<= 1) { return (a_u16
)x
; }
99 x1
<<= (A_U32_BSR(x
) + 1) >> 1;
102 x1
= (x0
+ x
/ x0
) >> 1;
105 #else /* Digit-by-digit */
106 a_u32 a
, b
= 1, y
= 0;
107 for (b
<<= sizeof(b
) * 8 - 2; b
> x
; b
>>= 2) {}
122 #if (__has_builtin(__builtin_clz) || A_PREREQ_GNUC(3, 4)) && (ULONG_MAX == A_U32_MAX)
123 #define A_U64_BSR(x) (63 - __builtin_clzll(x))
124 #elif __has_builtin(__builtin_clz) || A_PREREQ_GNUC(3, 4)
125 #define A_U64_BSR(x) (63 - __builtin_clzl(x))
126 #elif defined(_MSC_VER) && defined(_WIN64)
127 #pragma intrinsic(_BitScanReverse64)
128 #define A_U64_BSR(x) BitScanReverse64(x)
129 static A_INLINE
int A_U64_BSR(a_u64 x
)
132 _BitScanReverse64(&i
, x
);
135 #elif defined(_MSC_VER)
136 #define A_U64_BSR(x) BitScanReverse64(x)
137 static A_INLINE
int A_U64_BSR(a_u64 x
)
139 unsigned long i
= 0, hi
= 0;
140 _BitScanReverse(&i
, (a_u32
)x
);
141 if (_BitScanReverse(&hi
, x
>> 32))
147 #endif /* A_U64_BSR */
149 a_u32
a_u64_sqrt(a_u64 x
)
151 #if defined(A_U64_BSR) /* Newton's method */
153 if (x
<= 1) { return (a_u32
)x
; }
154 x1
<<= (A_U64_BSR(x
) + 1) >> 1;
157 x1
= (x0
+ x
/ x0
) >> 1;
160 #else /* Digit-by-digit */
161 a_u64 a
, b
= 1, y
= 0;
162 for (b
<<= sizeof(b
) * 8 - 2; b
> x
; b
>>= 2) {}
178 a_float
a_float_log1p(a_float x
)
180 a_float
volatile a
= x
+ 1;
181 a_float y
= a_float_log(a
);
182 if (x
< A_FLOAT_EPSILON
&& a
> 0)
184 a_float
volatile b
= a
- 1;
191 a_float
a_float_expm1(a_float x
)
193 static a_float
const P
[] = {
194 A_FLOAT_C(1.2617719307481059087798E-4),
195 A_FLOAT_C(3.0299440770744196129956E-2),
196 A_FLOAT_C(9.9999999999999999991025E-1),
198 static a_float
const Q
[] = {
199 A_FLOAT_C(3.0019850513866445504159E-6),
200 A_FLOAT_C(2.5244834034968410419224E-3),
201 A_FLOAT_C(2.2726554820815502876593E-1),
202 A_FLOAT_C(2.0000000000000000000897E-0),
207 if (isnan(x
) || x
> 0) { return x
; }
210 if (x
< -A_FLOAT_C(0.5) || x
> A_FLOAT_C(0.5))
212 return a_float_exp(x
) - 1;
215 y
= polevl(P
, A_LEN(P
) - 1, xx
) * x
;
216 y
/= polevl(Q
, A_LEN(Q
) - 1, xx
) - y
;
221 a_float
a_float_atan2(a_float x
, a_float y
)
223 if (x
> 0) { return a_float_atan(y
/ x
); }
226 if (y
>= 0) { return a_float_atan(y
/ x
) + A_FLOAT_PI
; }
227 return a_float_atan(y
/ x
) - A_FLOAT_PI
;
229 if (y
> 0) { return +A_FLOAT_PI
; }
230 if (y
< 0) { return -A_FLOAT_PI
; }
235 a_float
a_float_hypot(a_float x
, a_float y
)
237 a_float
const a
= a_float_abs(x
);
238 a_float
const b
= a_float_abs(y
);
239 if (isinf(x
) || isinf(y
))
254 return a_float_sqrt(x
* x
+ 1) * y
;
257 a_float
a_float_hypot3(a_float x
, a_float y
, a_float z
)
259 a_float
const a
= a_float_abs(x
);
260 a_float
const b
= a_float_abs(y
);
261 a_float
const c
= a_float_abs(z
);
263 if (isinf(x
) || isinf(y
) || isinf(z
))
267 if (w
< b
) { w
= b
; }
268 if (w
< c
) { w
= c
; }
269 if (w
== 0) { return 0; }
273 return a_float_sqrt(x
* x
+ y
* y
+ z
* z
) * w
;