s_nextafter.c revision 2116
12116Sjkh/* @(#)s_nextafter.c 5.1 93/09/24 */ 22116Sjkh/* 32116Sjkh * ==================================================== 42116Sjkh * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 52116Sjkh * 62116Sjkh * Developed at SunPro, a Sun Microsystems, Inc. business. 72116Sjkh * Permission to use, copy, modify, and distribute this 82116Sjkh * software is freely granted, provided that this notice 92116Sjkh * is preserved. 102116Sjkh * ==================================================== 112116Sjkh */ 122116Sjkh 132116Sjkh#ifndef lint 142116Sjkhstatic char rcsid[] = "$Id: s_nextafter.c,v 1.6 1994/08/18 23:07:13 jtc Exp $"; 152116Sjkh#endif 162116Sjkh 172116Sjkh/* IEEE functions 182116Sjkh * nextafter(x,y) 192116Sjkh * return the next machine floating-point number of x in the 202116Sjkh * direction toward y. 212116Sjkh * Special cases: 222116Sjkh */ 232116Sjkh 242116Sjkh#include "math.h" 252116Sjkh#include "math_private.h" 262116Sjkh 272116Sjkh#ifdef __STDC__ 282116Sjkh double nextafter(double x, double y) 292116Sjkh#else 302116Sjkh double nextafter(x,y) 312116Sjkh double x,y; 322116Sjkh#endif 332116Sjkh{ 342116Sjkh int32_t hx,hy,ix,iy; 352116Sjkh u_int32_t lx,ly; 362116Sjkh 372116Sjkh EXTRACT_WORDS(hx,lx,x); 382116Sjkh EXTRACT_WORDS(hy,ly,y); 392116Sjkh ix = hx&0x7fffffff; /* |x| */ 402116Sjkh iy = hy&0x7fffffff; /* |y| */ 412116Sjkh 422116Sjkh if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ 432116Sjkh ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */ 442116Sjkh return x+y; 452116Sjkh if(x==y) return x; /* x=y, return x */ 462116Sjkh if((ix|lx)==0) { /* x == 0 */ 472116Sjkh INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */ 482116Sjkh y = x*x; 492116Sjkh if(y==x) return y; else return x; /* raise underflow flag */ 502116Sjkh } 512116Sjkh if(hx>=0) { /* x > 0 */ 522116Sjkh if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ 532116Sjkh if(lx==0) hx -= 1; 542116Sjkh lx -= 1; 552116Sjkh } else { /* x < y, x += ulp */ 562116Sjkh lx += 1; 572116Sjkh if(lx==0) hx += 1; 582116Sjkh } 592116Sjkh } else { /* x < 0 */ 602116Sjkh if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */ 612116Sjkh if(lx==0) hx -= 1; 622116Sjkh lx -= 1; 632116Sjkh } else { /* x > y, x += ulp */ 642116Sjkh lx += 1; 652116Sjkh if(lx==0) hx += 1; 662116Sjkh } 672116Sjkh } 682116Sjkh hy = hx&0x7ff00000; 692116Sjkh if(hy>=0x7ff00000) return x+x; /* overflow */ 702116Sjkh if(hy<0x00100000) { /* underflow */ 712116Sjkh y = x*x; 722116Sjkh if(y!=x) { /* raise underflow flag */ 732116Sjkh INSERT_WORDS(y,hx,lx); 742116Sjkh return y; 752116Sjkh } 762116Sjkh } 772116Sjkh INSERT_WORDS(x,hx,lx); 782116Sjkh return x; 792116Sjkh} 80