e_hypotf.c revision 355395
11539Srgrimes/* e_hypotf.c -- float version of e_hypot.c.
21539Srgrimes * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
31539Srgrimes */
41539Srgrimes
51539Srgrimes/*
61539Srgrimes * ====================================================
71539Srgrimes * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
81539Srgrimes *
91539Srgrimes * Developed at SunPro, a Sun Microsystems, Inc. business.
101539Srgrimes * Permission to use, copy, modify, and distribute this
111539Srgrimes * software is freely granted, provided that this notice
121539Srgrimes * is preserved.
131539Srgrimes * ====================================================
141539Srgrimes */
151539Srgrimes
161539Srgrimes#include <sys/cdefs.h>
171539Srgrimes__FBSDID("$FreeBSD: stable/10/lib/msun/src/e_hypotf.c 355395 2019-12-04 17:45:34Z dim $");
181539Srgrimes
191539Srgrimes#include "math.h"
201539Srgrimes#include "math_private.h"
211539Srgrimes
221539Srgrimesfloat
231539Srgrimes__ieee754_hypotf(float x, float y)
241539Srgrimes{
251539Srgrimes	float a,b,t1,t2,y1,y2,w;
261539Srgrimes	int32_t j,k,ha,hb;
271539Srgrimes
281539Srgrimes	GET_FLOAT_WORD(ha,x);
291539Srgrimes	ha &= 0x7fffffff;
301539Srgrimes	GET_FLOAT_WORD(hb,y);
311539Srgrimes	hb &= 0x7fffffff;
321539Srgrimes	if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
3323657Speter	a = fabsf(a);
3455033Sbde	b = fabsf(b);
351539Srgrimes	if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */
361539Srgrimes	k=0;
371539Srgrimes	if(ha > 0x58800000) {	/* a>2**50 */
381539Srgrimes	   if(ha >= 0x7f800000) {	/* Inf or NaN */
391539Srgrimes	       /* Use original arg order iff result is NaN; quieten sNaNs. */
401539Srgrimes	       w = fabsf(x+0.0F)-fabsf(y+0.0F);
4193514Smike	       if(ha == 0x7f800000) w = a;
421539Srgrimes	       if(hb == 0x7f800000) w = b;
4393514Smike	       return w;
441539Srgrimes	   }
4593514Smike	   /* scale a and b by 2**-68 */
4693514Smike	   ha -= 0x22000000; hb -= 0x22000000;	k += 68;
4793514Smike	   SET_FLOAT_WORD(a,ha);
4893514Smike	   SET_FLOAT_WORD(b,hb);
4993514Smike	}
5093514Smike	if(hb < 0x26800000) {	/* b < 2**-50 */
5193514Smike	    if(hb <= 0x007fffff) {	/* subnormal b or 0 */
5293514Smike	        if(hb==0) return a;
5393514Smike		SET_FLOAT_WORD(t1,0x7e800000);	/* t1=2^126 */
5493514Smike		b *= t1;
5593514Smike		a *= t1;
5693514Smike		k -= 126;
5793514Smike	    } else {		/* scale a and b by 2^68 */
5893514Smike	        ha += 0x22000000; 	/* a *= 2^68 */
5993514Smike		hb += 0x22000000;	/* b *= 2^68 */
6093514Smike		k -= 68;
6193514Smike		SET_FLOAT_WORD(a,ha);
6293514Smike		SET_FLOAT_WORD(b,hb);
6393514Smike	    }
6493514Smike	}
6593514Smike    /* medium size a and b */
6693514Smike	w = a-b;
6793514Smike	if (w>b) {
6893514Smike	    SET_FLOAT_WORD(t1,ha&0xfffff000);
691539Srgrimes	    t2 = a-t1;
701539Srgrimes	    w  = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
711539Srgrimes	} else {
721539Srgrimes	    a  = a+a;
731539Srgrimes	    SET_FLOAT_WORD(y1,hb&0xfffff000);
741539Srgrimes	    y2 = b - y1;
751539Srgrimes	    SET_FLOAT_WORD(t1,(ha+0x00800000)&0xfffff000);
761539Srgrimes	    t2 = a - t1;
7798269Swollman	    w  = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
7837566Sbde	}
7937566Sbde	if(k!=0) {
8037566Sbde	    SET_FLOAT_WORD(t1,(127+k)<<23);
8137566Sbde	    return t1*w;
8237509Sdt	} else return w;
8337509Sdt}
841539Srgrimes