1 /* @(#)s_nextafter.c 5.1 93/09/24 */ 2 /* 3 * ==================================================== 4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 5 * 6 * Developed at SunPro, a Sun Microsystems, Inc. business. 7 * Permission to use, copy, modify, and distribute this 8 * software is freely granted, provided that this notice 9 * is preserved. 10 * ==================================================== 11 */ 12 13 #ifndef lint 14 static char rcsid[] = "$FreeBSD$"; 15 #endif 16 17 /* IEEE functions 18 * nextafter(x,y) 19 * return the next machine floating-point number of x in the 20 * direction toward y. 21 * Special cases: 22 */ 23 24 #include <sys/cdefs.h> 25 #include <float.h> 26 27 #include "fpmath.h" 28 #include "math.h" 29 #include "math_private.h" 30 31 #if LDBL_MAX_EXP != 0x4000 32 #error "Unsupported long double format" 33 #endif 34 35 long double 36 nextafterl(long double x, long double y) 37 { 38 volatile long double t; 39 union IEEEl2bits ux, uy; 40 41 ux.e = x; 42 uy.e = y; 43 44 if ((ux.bits.exp == 0x7fff && 45 ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl) != 0) || 46 (uy.bits.exp == 0x7fff && 47 ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) 48 return x+y; /* x or y is nan */ 49 if(x==y) return y; /* x=y, return y */ 50 if(x==0.0) { 51 ux.bits.manh = 0; /* return +-minsubnormal */ 52 ux.bits.manl = 1; 53 ux.bits.sign = uy.bits.sign; 54 t = ux.e*ux.e; 55 if(t==ux.e) return t; else return ux.e; /* raise underflow flag */ 56 } 57 if(x>0.0 ^ x<y) { /* x -= ulp */ 58 if(ux.bits.manl==0) { 59 if ((ux.bits.manh&~LDBL_NBIT)==0) 60 ux.bits.exp -= 1; 61 ux.bits.manh = (ux.bits.manh - 1) | (ux.bits.manh & LDBL_NBIT); 62 } 63 ux.bits.manl -= 1; 64 } else { /* x += ulp */ 65 ux.bits.manl += 1; 66 if(ux.bits.manl==0) { 67 ux.bits.manh = (ux.bits.manh + 1) | (ux.bits.manh & LDBL_NBIT); 68 if ((ux.bits.manh&~LDBL_NBIT)==0) 69 ux.bits.exp += 1; 70 } 71 } 72 if(ux.bits.exp==0x7fff) return x+x; /* overflow */ 73 if(ux.bits.exp==0) { /* underflow */ 74 mask_nbit_l(ux); 75 t = ux.e * ux.e; 76 if(t!=ux.e) /* raise underflow flag */ 77 return ux.e; 78 } 79 return ux.e; 80 } 81 82 __strong_reference(nextafterl, nexttowardl); 83