11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* e_sqrtf.c -- float version of e_sqrt.c. 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ==================================================== 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Developed at SunPro, a Sun Microsystems, Inc. business. 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * software is freely granted, provided that this notice 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is preserved. 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ==================================================== 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef lint 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char rcsid[] = "$FreeBSD: src/lib/msun/src/e_sqrtf.c,v 1.7 2002/05/28 18:15:04 alfred Exp $"; 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math.h" 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math_private.h" 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const float one = 1.0, tiny=1.0e-30; 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectfloat 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__ieee754_sqrtf(float x) 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project float z; 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int32_t sign = (int)0x80000000; 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int32_t ix,s,q,m,t,i; 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_int32_t r; 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project GET_FLOAT_WORD(ix,x); 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* take care of Inf and NaN */ 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if((ix&0x7f800000)==0x7f800000) { 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project sqrt(-inf)=sNaN */ 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* take care of zero */ 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ix<=0) { 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */ 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if(ix<0) 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* normalize x */ 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project m = (ix>>23); 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(m==0) { /* subnormal x */ 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for(i=0;(ix&0x00800000)==0;i++) ix<<=1; 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project m -= i-1; 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project m -= 127; /* unbias exponent */ 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ix = (ix&0x007fffff)|0x00800000; 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(m&1) /* odd m, double x to make it even */ 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ix += ix; 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project m >>= 1; /* m = [m/2] */ 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* generate sqrt(x) bit by bit */ 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ix += ix; 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project q = s = 0; /* q = sqrt(x) */ 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project r = 0x01000000; /* r = moving bit from right to left */ 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while(r!=0) { 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project t = s+r; 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(t<=ix) { 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project s = t+r; 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ix -= t; 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project q += r; 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ix += ix; 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project r>>=1; 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* use floating add to find out rounding direction */ 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(ix!=0) { 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project z = one-tiny; /* trigger inexact flag */ 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (z>=one) { 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project z = one+tiny; 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (z>one) 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project q += 2; 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project q += (q&1); 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ix = (q>>1)+0x3f000000; 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ix += (m <<23); 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project SET_FLOAT_WORD(z,ix); 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return z; 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 90