source: trunk/libs/newlib/src/newlib/libm/math/s_floor.c @ 567

Last change on this file since 567 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.5 KB
Line 
1
2/* @(#)s_floor.c 5.1 93/09/24 */
3/*
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 *
7 * Developed at SunPro, a Sun Microsystems, Inc. business.
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
12 */
13
14/*
15FUNCTION
16<<floor>>, <<floorf>>, <<ceil>>, <<ceilf>>---floor and ceiling
17INDEX
18        floor
19INDEX
20        floorf
21INDEX
22        ceil
23INDEX
24        ceilf
25
26SYNOPSIS
27        #include <math.h>
28        double floor(double <[x]>);
29        float floorf(float <[x]>);
30        double ceil(double <[x]>);
31        float ceilf(float <[x]>);
32
33DESCRIPTION
34<<floor>> and <<floorf>> find
35@tex
36$\lfloor x \rfloor$,
37@end tex
38the nearest integer less than or equal to <[x]>.
39<<ceil>> and <<ceilf>> find
40@tex
41$\lceil x\rceil$,
42@end tex
43the nearest integer greater than or equal to <[x]>.
44
45RETURNS
46<<floor>> and <<ceil>> return the integer result as a double.
47<<floorf>> and <<ceilf>> return the integer result as a float.
48
49PORTABILITY
50<<floor>> and <<ceil>> are ANSI.
51<<floorf>> and <<ceilf>> are extensions.
52
53
54*/
55
56/*
57 * floor(x)
58 * Return x rounded toward -inf to integral value
59 * Method:
60 *      Bit twiddling.
61 * Exception:
62 *      Inexact flag raised if x not equal to floor(x).
63 */
64
65#include "fdlibm.h"
66
67#ifndef _DOUBLE_IS_32BITS
68
69#ifdef __STDC__
70static const double huge = 1.0e300;
71#else
72static double huge = 1.0e300;
73#endif
74
75#ifdef __STDC__
76        double floor(double x)
77#else
78        double floor(x)
79        double x;
80#endif
81{
82        __int32_t i0,i1,j0;
83        __uint32_t i,j;
84        EXTRACT_WORDS(i0,i1,x);
85        j0 = ((i0>>20)&0x7ff)-0x3ff;
86        if(j0<20) {
87            if(j0<0) {  /* raise inexact if x != 0 */
88                if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
89                    if(i0>=0) {i0=i1=0;} 
90                    else if(((i0&0x7fffffff)|i1)!=0)
91                        { i0=0xbff00000;i1=0;}
92                }
93            } else {
94                i = (0x000fffff)>>j0;
95                if(((i0&i)|i1)==0) return x; /* x is integral */
96                if(huge+x>0.0) {        /* raise inexact flag */
97                    if(i0<0) i0 += (0x00100000)>>j0;
98                    i0 &= (~i); i1=0;
99                }
100            }
101        } else if (j0>51) {
102            if(j0==0x400) return x+x;   /* inf or NaN */
103            else return x;              /* x is integral */
104        } else {
105            i = ((__uint32_t)(0xffffffff))>>(j0-20);
106            if((i1&i)==0) return x;     /* x is integral */
107            if(huge+x>0.0) {            /* raise inexact flag */
108                if(i0<0) {
109                    if(j0==20) i0+=1; 
110                    else {
111                        j = i1+(1<<(52-j0));
112                        if(j<i1) i0 +=1 ;       /* got a carry */
113                        i1=j;
114                    }
115                }
116                i1 &= (~i);
117            }
118        }
119        INSERT_WORDS(x,i0,i1);
120        return x;
121}
122
123#endif /* _DOUBLE_IS_32BITS */
Note: See TracBrowser for help on using the repository browser.