| 1 | #include "libm.h" |
| 2 | |
| 3 | float sinhf(float x) |
| 4 | { |
| 5 | 	union {float f; uint32_t i;} u = {.f = x}; |
| 6 | 	uint32_t w; |
| 7 | 	float t, h, absx; |
| 8 | |
| 9 | 	h = 0.5; |
| 10 | 	if (u.i >> 31) |
| 11 | 		h = -h; |
| 12 | 	/* |x| */ |
| 13 | 	u.i &= 0x7fffffff; |
| 14 | 	absx = u.f; |
| 15 | 	w = u.i; |
| 16 | |
| 17 | 	/* |x| < log(FLT_MAX) */ |
| 18 | 	if (w < 0x42b17217) { |
| 19 | 		t = expm1f(absx); |
| 20 | 		if (w < 0x3f800000) { |
| 21 | 			if (w < 0x3f800000 - (12<<23)) |
| 22 | 				return x; |
| 23 | 			return h*(2*t - t*t/(t+1)); |
| 24 | 		} |
| 25 | 		return h*(t + t/(t+1)); |
| 26 | 	} |
| 27 | |
| 28 | 	/* |x| > logf(FLT_MAX) or nan */ |
| 29 | 	t = __expo2f(absx, 2*h); |
| 30 | 	return t; |
| 31 | } |