xref: /haiku/src/system/libroot/posix/musl/math/hypotf.c (revision f504f61099b010fbfa94b1cc63d2e9072c7f7185)
1*f504f610SAugustin Cavalier #include <math.h>
2*f504f610SAugustin Cavalier #include <stdint.h>
3*f504f610SAugustin Cavalier 
hypotf(float x,float y)4*f504f610SAugustin Cavalier float hypotf(float x, float y)
5*f504f610SAugustin Cavalier {
6*f504f610SAugustin Cavalier 	union {float f; uint32_t i;} ux = {x}, uy = {y}, ut;
7*f504f610SAugustin Cavalier 	float_t z;
8*f504f610SAugustin Cavalier 
9*f504f610SAugustin Cavalier 	ux.i &= -1U>>1;
10*f504f610SAugustin Cavalier 	uy.i &= -1U>>1;
11*f504f610SAugustin Cavalier 	if (ux.i < uy.i) {
12*f504f610SAugustin Cavalier 		ut = ux;
13*f504f610SAugustin Cavalier 		ux = uy;
14*f504f610SAugustin Cavalier 		uy = ut;
15*f504f610SAugustin Cavalier 	}
16*f504f610SAugustin Cavalier 
17*f504f610SAugustin Cavalier 	x = ux.f;
18*f504f610SAugustin Cavalier 	y = uy.f;
19*f504f610SAugustin Cavalier 	if (uy.i == 0xff<<23)
20*f504f610SAugustin Cavalier 		return y;
21*f504f610SAugustin Cavalier 	if (ux.i >= 0xff<<23 || uy.i == 0 || ux.i - uy.i >= 25<<23)
22*f504f610SAugustin Cavalier 		return x + y;
23*f504f610SAugustin Cavalier 
24*f504f610SAugustin Cavalier 	z = 1;
25*f504f610SAugustin Cavalier 	if (ux.i >= (0x7f+60)<<23) {
26*f504f610SAugustin Cavalier 		z = 0x1p90f;
27*f504f610SAugustin Cavalier 		x *= 0x1p-90f;
28*f504f610SAugustin Cavalier 		y *= 0x1p-90f;
29*f504f610SAugustin Cavalier 	} else if (uy.i < (0x7f-60)<<23) {
30*f504f610SAugustin Cavalier 		z = 0x1p-90f;
31*f504f610SAugustin Cavalier 		x *= 0x1p90f;
32*f504f610SAugustin Cavalier 		y *= 0x1p90f;
33*f504f610SAugustin Cavalier 	}
34*f504f610SAugustin Cavalier 	return z*sqrtf((double)x*x + (double)y*y);
35*f504f610SAugustin Cavalier }
36