1 | /* s_floorf.c -- float version of s_floor.c. |
2 | * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. |
3 | */ |
4 | |
5 | /* |
6 | * ==================================================== |
7 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
8 | * |
9 | * Developed at SunPro, a Sun Microsystems, Inc. business. |
10 | * Permission to use, copy, modify, and distribute this |
11 | * software is freely granted, provided that this notice |
12 | * is preserved. |
13 | * ==================================================== |
14 | */ |
15 | |
16 | /* |
17 | * floorf(x) |
18 | * Return x rounded toward -inf to integral value |
19 | * Method: |
20 | * Bit twiddling. |
21 | */ |
22 | |
23 | #define NO_MATH_REDIRECT |
24 | #include <math.h> |
25 | #include <math_private.h> |
26 | #include <libm-alias-float.h> |
27 | #include <math-use-builtins.h> |
28 | |
29 | float |
30 | __floorf (float x) |
31 | { |
32 | #if USE_FLOORF_BUILTIN |
33 | return __builtin_floorf (x); |
34 | #else |
35 | /* Use generic implementation. */ |
36 | int32_t i0, j0; |
37 | uint32_t i; |
38 | GET_FLOAT_WORD (i0, x); |
39 | j0 = ((i0 >> 23) & 0xff) - 0x7f; |
40 | if (j0 < 23) |
41 | { |
42 | if (j0 < 0) |
43 | { |
44 | /* return 0 * sign (x) if |x| < 1 */ |
45 | if (i0 >= 0) |
46 | i0 = 0; |
47 | else if ((i0 & 0x7fffffff) != 0) |
48 | i0 = 0xbf800000; |
49 | } |
50 | else |
51 | { |
52 | i = (0x007fffff) >> j0; |
53 | if ((i0 & i) == 0) |
54 | return x; /* x is integral */ |
55 | if (i0 < 0) |
56 | i0 += (0x00800000) >> j0; |
57 | i0 &= (~i); |
58 | } |
59 | } |
60 | else |
61 | { |
62 | if (__glibc_unlikely (j0 == 0x80)) |
63 | return x + x; /* inf or NaN */ |
64 | else |
65 | return x; /* x is integral */ |
66 | } |
67 | SET_FLOAT_WORD (x, i0); |
68 | return x; |
69 | #endif /* ! USE_FLOORF_BUILTIN */ |
70 | } |
71 | #ifndef __floorf |
72 | libm_alias_float (__floor, floor) |
73 | #endif |
74 | |