]>
Commit | Line | Data |
---|---|---|
c6251f03 RM |
1 | /* Single precision version of nexttoward.c. |
2 | Conversion to IEEE single float by Jakub Jelinek, jj@ultra.linux.cz. */ | |
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 | /* IEEE functions | |
15 | * __nexttowardfd(x,y) | |
16 | * return the next machine floating-point number of x in the | |
17 | * direction toward y. | |
18 | * This is for machines which use different binary type for double and | |
19 | * long double conditionally, y is long double equal to double. | |
20 | * Special cases: | |
21 | */ | |
22 | ||
23 | #include <math_ldbl_opt.h> | |
24 | ||
25 | float __nldbl_nexttowardf(float x, double y); | |
26 | ||
27 | float __nldbl_nexttowardf(float x, double y) | |
28 | { | |
29 | int32_t hx,hy,ix,iy; | |
30 | u_int32_t ly; | |
31 | ||
32 | GET_FLOAT_WORD(hx,x); | |
33 | EXTRACT_WORDS(hy,ly,y); | |
34 | ix = hx&0x7fffffff; /* |x| */ | |
35 | iy = hy&0x7fffffff; /* |y| */ | |
36 | ||
37 | if((ix>0x7f800000) || /* x is nan */ | |
38 | ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */ | |
39 | return x+y; | |
40 | if((double) x==y) return y; /* x=y, return y */ | |
41 | if(ix==0) { /* x == 0 */ | |
11bf311e | 42 | float x2; |
c6251f03 | 43 | SET_FLOAT_WORD(x,(u_int32_t)(hy&0x80000000)|1);/* return +-minsub*/ |
11bf311e UD |
44 | x2 = x*x; |
45 | if(x2==x) return x2; else return x; /* raise underflow flag */ | |
c6251f03 RM |
46 | } |
47 | if(hx>=0) { /* x > 0 */ | |
48 | if(hy<0||(ix>>23)>(iy>>20)-0x380 | |
49 | || ((ix>>23)==(iy>>20)-0x380 | |
50 | && (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x > y, x -= ulp */ | |
51 | hx -= 1; | |
52 | else /* x < y, x += ulp */ | |
53 | hx += 1; | |
54 | } else { /* x < 0 */ | |
55 | if(hy>=0||(ix>>23)>(iy>>20)-0x380 | |
56 | || ((ix>>23)==(iy>>20)-0x380 | |
57 | && (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff))) /* x < y, x -= ulp */ | |
58 | hx -= 1; | |
59 | else /* x > y, x += ulp */ | |
60 | hx += 1; | |
61 | } | |
62 | hy = hx&0x7f800000; | |
11bf311e UD |
63 | if(hy>=0x7f800000) return x+x; /* overflow */ |
64 | if(hy<0x00800000) { /* underflow */ | |
65 | float x2 = x*x; | |
66 | if(x2!=x) { /* raise underflow flag */ | |
67 | SET_FLOAT_WORD(x2,hx); | |
68 | return x2; | |
69 | } | |
c6251f03 RM |
70 | } |
71 | SET_FLOAT_WORD(x,hx); | |
72 | return x; | |
73 | } | |
74 | ||
75 | #if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) | |
76 | compat_symbol (libm, __nldbl_nexttowardf, nexttowardf, GLIBC_2_1); | |
77 | #endif |