source: trunk/libs/newlib/src/newlib/libm/common/s_nextafter.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.7 KB
Line 
1
2/* @(#)s_nextafter.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       <<nextafter>>, <<nextafterf>>---get next number
17
18INDEX
19        nextafter
20INDEX
21        nextafterf
22
23SYNOPSIS
24       #include <math.h>
25       double nextafter(double <[val]>, double <[dir]>);
26       float nextafterf(float <[val]>, float <[dir]>);
27
28DESCRIPTION
29<<nextafter>> returns the double-precision floating-point number
30closest to <[val]> in the direction toward <[dir]>.  <<nextafterf>>
31performs the same operation in single precision.  For example,
32<<nextafter(0.0,1.0)>> returns the smallest positive number which is
33representable in double precision.
34
35RETURNS
36Returns the next closest number to <[val]> in the direction toward
37<[dir]>.
38
39PORTABILITY
40        Neither <<nextafter>> nor <<nextafterf>> is required by ANSI C
41        or by the System V Interface Definition (Issue 2).
42*/
43
44/* IEEE functions
45 *      nextafter(x,y)
46 *      return the next machine floating-point number of x in the
47 *      direction toward y.
48 *   Special cases:
49 */
50
51#include "fdlibm.h"
52
53#ifndef _DOUBLE_IS_32BITS
54
55#ifdef __STDC__
56        double nextafter(double x, double y)
57#else
58        double nextafter(x,y)
59        double x,y;
60#endif
61{
62        __int32_t       hx,hy,ix,iy;
63        __uint32_t lx,ly;
64
65        EXTRACT_WORDS(hx,lx,x);
66        EXTRACT_WORDS(hy,ly,y);
67        ix = hx&0x7fffffff;             /* |x| */
68        iy = hy&0x7fffffff;             /* |y| */
69
70        if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */ 
71           ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */ 
72           return x+y;                         
73        if(x==y) return x;              /* x=y, return x */
74        if((ix|lx)==0) {                        /* x == 0 */
75            INSERT_WORDS(x,hy&0x80000000,1);    /* return +-minsubnormal */
76            y = x*x;
77            if(y==x) return y; else return x;   /* raise underflow flag */
78        } 
79        if(hx>=0) {                             /* x > 0 */
80            if(hx>hy||((hx==hy)&&(lx>ly))) {    /* x > y, x -= ulp */
81                if(lx==0) hx -= 1;
82                lx -= 1;
83            } else {                            /* x < y, x += ulp */
84                lx += 1;
85                if(lx==0) hx += 1;
86            }
87        } else {                                /* x < 0 */
88            if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
89                if(lx==0) hx -= 1;
90                lx -= 1;
91            } else {                            /* x > y, x += ulp */
92                lx += 1;
93                if(lx==0) hx += 1;
94            }
95        }
96        hy = hx&0x7ff00000;
97        if(hy>=0x7ff00000) return x+x;  /* overflow  */
98        if(hy<0x00100000) {             /* underflow */
99            y = x*x;
100            if(y!=x) {          /* raise underflow flag */
101                INSERT_WORDS(y,hx,lx);
102                return y;
103            }
104        }
105        INSERT_WORDS(x,hx,lx);
106        return x;
107}
108
109#endif /* _DOUBLE_IS_32BITS */
Note: See TracBrowser for help on using the repository browser.