Rich Felker | b69f695 | 2012-03-13 01:17:53 -0400 | [diff] [blame] | 1 | #include "libm.h" |
2 | |||||
Rich Felker | b69f695 | 2012-03-13 01:17:53 -0400 | [diff] [blame] | 3 | float floorf(float x) |
4 | { | ||||
Szabolcs Nagy | d1a2ead | 2013-09-03 03:27:02 +0000 | [diff] [blame] | 5 | union {float f; uint32_t i;} u = {x}; |
6 | int e = (int)(u.i >> 23 & 0xff) - 0x7f; | ||||
7 | uint32_t m; | ||||
Rich Felker | b69f695 | 2012-03-13 01:17:53 -0400 | [diff] [blame] | 8 | |
Szabolcs Nagy | d1a2ead | 2013-09-03 03:27:02 +0000 | [diff] [blame] | 9 | if (e >= 23) |
10 | return x; | ||||
11 | if (e >= 0) { | ||||
12 | m = 0x007fffff >> e; | ||||
13 | if ((u.i & m) == 0) | ||||
14 | return x; | ||||
15 | FORCE_EVAL(x + 0x1p120f); | ||||
16 | if (u.i >> 31) | ||||
17 | u.i += m; | ||||
18 | u.i &= ~m; | ||||
Rich Felker | b69f695 | 2012-03-13 01:17:53 -0400 | [diff] [blame] | 19 | } else { |
Szabolcs Nagy | d1a2ead | 2013-09-03 03:27:02 +0000 | [diff] [blame] | 20 | FORCE_EVAL(x + 0x1p120f); |
21 | if (u.i >> 31 == 0) | ||||
22 | u.i = 0; | ||||
23 | else if (u.i << 1) | ||||
24 | u.f = -1.0; | ||||
Rich Felker | b69f695 | 2012-03-13 01:17:53 -0400 | [diff] [blame] | 25 | } |
Szabolcs Nagy | d1a2ead | 2013-09-03 03:27:02 +0000 | [diff] [blame] | 26 | return u.f; |
Rich Felker | b69f695 | 2012-03-13 01:17:53 -0400 | [diff] [blame] | 27 | } |