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 #include <sys/cdefs.h> 14 /* IEEE functions 15 * nextafter(x,y) 16 * return the next machine floating-point number of x in the 17 * direction toward y. 18 * Special cases: 19 */ 20 21 #include <float.h> 22 23 #include "fpmath.h" 24 #include "math.h" 25 #include "math_private.h" 26 27 #if LDBL_MAX_EXP != 0x4000 28 #error "Unsupported long double format" 29 #endif 30 31 long double 32 nextafterl(long double x, long double y) 33 { 34 volatile long double t; 35 union IEEEl2bits ux, uy; 36 37 ux.e = x; 38 uy.e = y; 39 40 if ((ux.bits.exp == 0x7fff && 41 ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl) != 0) || 42 (uy.bits.exp == 0x7fff && 43 ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) 44 return x+y; /* x or y is nan */ 45 if(x==y) return y; /* x=y, return y */ 46 if(x==0.0) { 47 ux.bits.manh = 0; /* return +-minsubnormal */ 48 ux.bits.manl = 1; 49 ux.bits.sign = uy.bits.sign; 50 t = ux.e*ux.e; 51 if(t==ux.e) return t; else return ux.e; /* raise underflow flag */ 52 } 53 if(x>0.0 ^ x<y) { /* x -= ulp */ 54 if(ux.bits.manl==0) { 55 if ((ux.bits.manh&~LDBL_NBIT)==0) 56 ux.bits.exp -= 1; 57 ux.bits.manh = (ux.bits.manh - 1) | (ux.bits.manh & LDBL_NBIT); 58 } 59 ux.bits.manl -= 1; 60 } else { /* x += ulp */ 61 ux.bits.manl += 1; 62 if(ux.bits.manl==0) { 63 ux.bits.manh = (ux.bits.manh + 1) | (ux.bits.manh & LDBL_NBIT); 64 if ((ux.bits.manh&~LDBL_NBIT)==0) 65 ux.bits.exp += 1; 66 } 67 } 68 if(ux.bits.exp==0x7fff) return x+x; /* overflow */ 69 if(ux.bits.exp==0) { /* underflow */ 70 mask_nbit_l(ux); 71 t = ux.e * ux.e; 72 if(t!=ux.e) /* raise underflow flag */ 73 return ux.e; 74 } 75 return ux.e; 76 } 77 78 __strong_reference(nextafterl, nexttowardl); 79