1 | /* sf_nextafter.c -- float version of s_nextafter.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 | #include "fdlibm.h" |
---|
17 | |
---|
18 | #ifdef __STDC__ |
---|
19 | float nextafterf(float x, float y) |
---|
20 | #else |
---|
21 | float nextafterf(x,y) |
---|
22 | float x,y; |
---|
23 | #endif |
---|
24 | { |
---|
25 | __int32_t hx,hy,ix,iy; |
---|
26 | |
---|
27 | GET_FLOAT_WORD(hx,x); |
---|
28 | GET_FLOAT_WORD(hy,y); |
---|
29 | ix = hx&0x7fffffff; /* |x| */ |
---|
30 | iy = hy&0x7fffffff; /* |y| */ |
---|
31 | |
---|
32 | if(FLT_UWORD_IS_NAN(ix) || |
---|
33 | FLT_UWORD_IS_NAN(iy)) |
---|
34 | return x+y; |
---|
35 | if(x==y) return x; /* x=y, return x */ |
---|
36 | if(FLT_UWORD_IS_ZERO(ix)) { /* x == 0 */ |
---|
37 | SET_FLOAT_WORD(x,(hy&0x80000000)|FLT_UWORD_MIN); |
---|
38 | y = x*x; |
---|
39 | if(y==x) return y; else return x; /* raise underflow flag */ |
---|
40 | } |
---|
41 | if(hx>=0) { /* x > 0 */ |
---|
42 | if(hx>hy) { /* x > y, x -= ulp */ |
---|
43 | hx -= 1; |
---|
44 | } else { /* x < y, x += ulp */ |
---|
45 | hx += 1; |
---|
46 | } |
---|
47 | } else { /* x < 0 */ |
---|
48 | if(hy>=0||hx>hy){ /* x < y, x -= ulp */ |
---|
49 | hx -= 1; |
---|
50 | } else { /* x > y, x += ulp */ |
---|
51 | hx += 1; |
---|
52 | } |
---|
53 | } |
---|
54 | hy = hx&0x7f800000; |
---|
55 | if(hy>FLT_UWORD_MAX) return x+x; /* overflow */ |
---|
56 | if(hy<0x00800000) { /* underflow */ |
---|
57 | y = x*x; |
---|
58 | if(y!=x) { /* raise underflow flag */ |
---|
59 | SET_FLOAT_WORD(y,hx); |
---|
60 | return y; |
---|
61 | } |
---|
62 | } |
---|
63 | SET_FLOAT_WORD(x,hx); |
---|
64 | return x; |
---|
65 | } |
---|
66 | |
---|
67 | #ifdef _DOUBLE_IS_32BITS |
---|
68 | |
---|
69 | #ifdef __STDC__ |
---|
70 | double nextafter(double x, double y) |
---|
71 | #else |
---|
72 | double nextafter(x,y) |
---|
73 | double x,y; |
---|
74 | #endif |
---|
75 | { |
---|
76 | return (double) nextafterf((float) x, (float) x); |
---|
77 | } |
---|
78 | |
---|
79 | #endif /* defined(_DOUBLE_IS_32BITS) */ |
---|