2 * ====================================================
3 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 * Developed at SunPro, a Sun Microsystems, Inc. business.
6 * Permission to use, copy, modify, and distribute this
7 * software is freely granted, provided that this notice
9 * ====================================================
13 static char rcsid
[] = "$FreeBSD: src/lib/msun/src/e_hypotl.c,v 1.3 2011/10/16 05:36:39 das Exp $";
20 #include "math_private.h"
22 #define GET_LDBL_MAN(h, l, v) do { \
23 union IEEEl2bits uv; \
31 #define GET_HIGH_WORD(i, v) GET_LDBL_EXPSIGN(i, v)
33 #define SET_HIGH_WORD(v, i) SET_LDBL_EXPSIGN(v, i)
35 #define DESW(exp) (exp) /* delta expsign word */
36 #define ESW(exp) (MAX_EXP - 1 + (exp)) /* expsign word */
37 #define MANT_DIG LDBL_MANT_DIG
38 #define MAX_EXP LDBL_MAX_EXP
40 #if LDBL_MANL_SIZE > 32
41 typedef uint64_t man_t
;
43 typedef uint32_t man_t
;
47 hypotl(long double x
, long double y
)
49 long double a
=x
,b
=y
,t1
,t2
,y1
,y2
,w
;
56 if(hb
> ha
) {a
=y
;b
=x
;j
=ha
; ha
=hb
;hb
=j
;} else {a
=x
;b
=y
;}
59 if((ha
-hb
)>DESW(MANT_DIG
+7)) {return a
+b
;} /* x/y > 2**(MANT_DIG+7) */
61 if(ha
> ESW(MAX_EXP
/2-12)) { /* a>2**(MAX_EXP/2-12) */
62 if(ha
>= ESW(MAX_EXP
)) { /* Inf or NaN */
64 /* Use original arg order iff result is NaN; quieten sNaNs. */
65 w
= fabsl(x
+0.0)-fabsl(y
+0.0);
66 GET_LDBL_MAN(manh
,manl
,a
);
67 if (manh
== LDBL_NBIT
&& manl
== 0) w
= a
;
68 GET_LDBL_MAN(manh
,manl
,b
);
69 if (hb
>= ESW(MAX_EXP
) && manh
== LDBL_NBIT
&& manl
== 0) w
= b
;
72 /* scale a and b by 2**-(MAX_EXP/2+88) */
73 ha
-= DESW(MAX_EXP
/2+88); hb
-= DESW(MAX_EXP
/2+88);
78 if(hb
< ESW(-(MAX_EXP
/2-12))) { /* b < 2**-(MAX_EXP/2-12) */
79 if(hb
<= 0) { /* subnormal b or 0 */
81 GET_LDBL_MAN(manh
,manl
,b
);
82 if((manh
|manl
)==0) return a
;
84 SET_HIGH_WORD(t1
,ESW(MAX_EXP
-2)); /* t1=2^(MAX_EXP-2) */
88 } else { /* scale a and b by 2^(MAX_EXP/2+88) */
89 ha
+= DESW(MAX_EXP
/2+88);
90 hb
+= DESW(MAX_EXP
/2+88);
96 /* medium size a and b */
101 uv
.e
= t1
; uv
.bits
.manl
= 0; t1
= uv
.e
;
103 w
= sqrtl(t1
*t1
-(b
*(-b
)-t2
*(a
+t1
)));
108 uv
.e
= y1
; uv
.bits
.manl
= 0; y1
= uv
.e
;
111 uv
.e
= t1
; uv
.bits
.manl
= 0; t1
= uv
.e
;
113 w
= sqrtl(t1
*y1
-(w
*(-w
)-(t1
*y2
+t2
*b
)));
118 GET_HIGH_WORD(high
,t1
);
119 SET_HIGH_WORD(t1
,high
+DESW(k
));