11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* @(#)s_nextafter.c 5.1 93/09/24 */ 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ==================================================== 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Developed at SunPro, a Sun Microsystems, Inc. business. 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * software is freely granted, provided that this notice 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is preserved. 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ==================================================== 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 13a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#include <sys/cdefs.h> 14a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes__FBSDID("$FreeBSD$"); 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* IEEE functions 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * nextafter(x,y) 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * return the next machine floating-point number of x in the 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * direction toward y. 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Special cases: 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <float.h> 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "fpmath.h" 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math.h" 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math_private.h" 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if LDBL_MAX_EXP != 0x4000 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#error "Unsupported long double format" 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectlong double 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectnextafterl(long double x, long double y) 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project volatile long double t; 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project union IEEEl2bits ux, uy; 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.e = x; 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project uy.e = y; 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((ux.bits.exp == 0x7fff && 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl) != 0) || 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (uy.bits.exp == 0x7fff && 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return x+y; /* x or y is nan */ 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(x==y) return y; /* x=y, return y */ 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(x==0.0) { 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.bits.manh = 0; /* return +-minsubnormal */ 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.bits.manl = 1; 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.bits.sign = uy.bits.sign; 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project t = ux.e*ux.e; 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(t==ux.e) return t; else return ux.e; /* raise underflow flag */ 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(x>0.0 ^ x<y) { /* x -= ulp */ 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ux.bits.manl==0) { 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((ux.bits.manh&~LDBL_NBIT)==0) 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.bits.exp -= 1; 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.bits.manh = (ux.bits.manh - 1) | (ux.bits.manh & LDBL_NBIT); 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.bits.manl -= 1; 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { /* x += ulp */ 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.bits.manl += 1; 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ux.bits.manl==0) { 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.bits.manh = (ux.bits.manh + 1) | (ux.bits.manh & LDBL_NBIT); 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ((ux.bits.manh&~LDBL_NBIT)==0) 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ux.bits.exp += 1; 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ux.bits.exp==0x7fff) return x+x; /* overflow */ 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ux.bits.exp==0) { /* underflow */ 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mask_nbit_l(ux); 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project t = ux.e * ux.e; 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(t!=ux.e) /* raise underflow flag */ 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return ux.e; 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return ux.e; 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__strong_reference(nextafterl, nexttowardl); 81