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