Skip to content

Commit 4eec460

Browse files
committed
Added hypotf and hypotl implementations
1 parent 239eed7 commit 4eec460

File tree

3 files changed

+68
-8
lines changed

3 files changed

+68
-8
lines changed

src/libc/hypot.c

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/libc/hypotf.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
4+
typedef union F32_pun {
5+
float flt;
6+
uint32_t bin;
7+
} F32_pun;
8+
9+
float hypotf(float arg_x, float arg_y) {
10+
F32_pun x, y;
11+
x.flt = fabsf(arg_x);
12+
y.flt = fabsf(arg_y);
13+
if (x.bin < y.bin) {
14+
float temp = x.flt;
15+
x.flt = y.flt;
16+
y.flt = temp;
17+
}
18+
// x >= y, or x is NaN
19+
if (isfinite(x.flt)) {
20+
int expon;
21+
// scale the arguments to prevent overflow/underflow
22+
x.flt = frexpf(x.flt, &expon);
23+
y.flt = ldexpf(y.flt, -expon);
24+
float ret = sqrtf(x.flt * x.flt + y.flt * y.flt);
25+
return ldexpf(ret, expon);
26+
}
27+
if (isinf(y.flt)) {
28+
// return infinity, even if the other argument is NaN
29+
return y.flt;
30+
}
31+
// x is infinity/NaN
32+
return x.flt;
33+
}
34+
35+
double hypot(double, double) __attribute__((alias("hypotf")));

src/libc/hypotl.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
4+
typedef union F64_pun {
5+
long double flt;
6+
uint64_t bin;
7+
} F64_pun;
8+
9+
long double hypotl(long double arg_x, long double arg_y) {
10+
F64_pun x, y;
11+
x.flt = fabsl(arg_x);
12+
y.flt = fabsl(arg_y);
13+
if (x.bin < y.bin) {
14+
long double temp = x.flt;
15+
x.flt = y.flt;
16+
y.flt = temp;
17+
}
18+
// x >= y, or x is NaN
19+
if (isfinite(x.flt)) {
20+
int expon;
21+
// scale the arguments to prevent overflow/underflow
22+
x.flt = frexpl(x.flt, &expon);
23+
y.flt = ldexpl(y.flt, -expon);
24+
long double ret = sqrtl(x.flt * x.flt + y.flt * y.flt);
25+
return ldexpl(ret, expon);
26+
}
27+
if (isinf(y.flt)) {
28+
// return infinity, even if the other argument is NaN
29+
return y.flt;
30+
}
31+
// x is infinity/NaN
32+
return x.flt;
33+
}

0 commit comments

Comments
 (0)