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