13a8617a8SJordan K. Hubbard /* @(#)s_nextafter.c 5.1 93/09/24 */ 23a8617a8SJordan K. Hubbard /* 33a8617a8SJordan K. Hubbard * ==================================================== 43a8617a8SJordan K. Hubbard * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 53a8617a8SJordan K. Hubbard * 63a8617a8SJordan K. Hubbard * Developed at SunPro, a Sun Microsystems, Inc. business. 73a8617a8SJordan K. Hubbard * Permission to use, copy, modify, and distribute this 83a8617a8SJordan K. Hubbard * software is freely granted, provided that this notice 93a8617a8SJordan K. Hubbard * is preserved. 103a8617a8SJordan K. Hubbard * ==================================================== 113a8617a8SJordan K. Hubbard */ 123a8617a8SJordan K. Hubbard 133a8617a8SJordan K. Hubbard #ifndef lint 143a8617a8SJordan K. Hubbard static char rcsid[] = "$Id: s_nextafter.c,v 1.6 1994/08/18 23:07:13 jtc Exp $"; 153a8617a8SJordan K. Hubbard #endif 163a8617a8SJordan K. Hubbard 173a8617a8SJordan K. Hubbard /* IEEE functions 183a8617a8SJordan K. Hubbard * nextafter(x,y) 193a8617a8SJordan K. Hubbard * return the next machine floating-point number of x in the 203a8617a8SJordan K. Hubbard * direction toward y. 213a8617a8SJordan K. Hubbard * Special cases: 223a8617a8SJordan K. Hubbard */ 233a8617a8SJordan K. Hubbard 243a8617a8SJordan K. Hubbard #include "math.h" 253a8617a8SJordan K. Hubbard #include "math_private.h" 263a8617a8SJordan K. Hubbard 273a8617a8SJordan K. Hubbard #ifdef __STDC__ 283a8617a8SJordan K. Hubbard double nextafter(double x, double y) 293a8617a8SJordan K. Hubbard #else 303a8617a8SJordan K. Hubbard double nextafter(x,y) 313a8617a8SJordan K. Hubbard double x,y; 323a8617a8SJordan K. Hubbard #endif 333a8617a8SJordan K. Hubbard { 343a8617a8SJordan K. Hubbard int32_t hx,hy,ix,iy; 353a8617a8SJordan K. Hubbard u_int32_t lx,ly; 363a8617a8SJordan K. Hubbard 373a8617a8SJordan K. Hubbard EXTRACT_WORDS(hx,lx,x); 383a8617a8SJordan K. Hubbard EXTRACT_WORDS(hy,ly,y); 393a8617a8SJordan K. Hubbard ix = hx&0x7fffffff; /* |x| */ 403a8617a8SJordan K. Hubbard iy = hy&0x7fffffff; /* |y| */ 413a8617a8SJordan K. Hubbard 423a8617a8SJordan K. Hubbard if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ 433a8617a8SJordan K. Hubbard ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */ 443a8617a8SJordan K. Hubbard return x+y; 453a8617a8SJordan K. Hubbard if(x==y) return x; /* x=y, return x */ 463a8617a8SJordan K. Hubbard if((ix|lx)==0) { /* x == 0 */ 473a8617a8SJordan K. Hubbard INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */ 483a8617a8SJordan K. Hubbard y = x*x; 493a8617a8SJordan K. Hubbard if(y==x) return y; else return x; /* raise underflow flag */ 503a8617a8SJordan K. Hubbard } 513a8617a8SJordan K. Hubbard if(hx>=0) { /* x > 0 */ 523a8617a8SJordan K. Hubbard if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ 533a8617a8SJordan K. Hubbard if(lx==0) hx -= 1; 543a8617a8SJordan K. Hubbard lx -= 1; 553a8617a8SJordan K. Hubbard } else { /* x < y, x += ulp */ 563a8617a8SJordan K. Hubbard lx += 1; 573a8617a8SJordan K. Hubbard if(lx==0) hx += 1; 583a8617a8SJordan K. Hubbard } 593a8617a8SJordan K. Hubbard } else { /* x < 0 */ 603a8617a8SJordan K. Hubbard if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */ 613a8617a8SJordan K. Hubbard if(lx==0) hx -= 1; 623a8617a8SJordan K. Hubbard lx -= 1; 633a8617a8SJordan K. Hubbard } else { /* x > y, x += ulp */ 643a8617a8SJordan K. Hubbard lx += 1; 653a8617a8SJordan K. Hubbard if(lx==0) hx += 1; 663a8617a8SJordan K. Hubbard } 673a8617a8SJordan K. Hubbard } 683a8617a8SJordan K. Hubbard hy = hx&0x7ff00000; 693a8617a8SJordan K. Hubbard if(hy>=0x7ff00000) return x+x; /* overflow */ 703a8617a8SJordan K. Hubbard if(hy<0x00100000) { /* underflow */ 713a8617a8SJordan K. Hubbard y = x*x; 723a8617a8SJordan K. Hubbard if(y!=x) { /* raise underflow flag */ 733a8617a8SJordan K. Hubbard INSERT_WORDS(y,hx,lx); 743a8617a8SJordan K. Hubbard return y; 753a8617a8SJordan K. Hubbard } 763a8617a8SJordan K. Hubbard } 773a8617a8SJordan K. Hubbard INSERT_WORDS(x,hx,lx); 783a8617a8SJordan K. Hubbard return x; 793a8617a8SJordan K. Hubbard } 80