1 /* ef_hypot.c -- float version of e_hypot.c.
2  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
3  */
4 
5 /*
6  * ====================================================
7  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8  *
9  * Developed at SunPro, a Sun Microsystems, Inc. business.
10  * Permission to use, copy, modify, and distribute this
11  * software is freely granted, provided that this notice
12  * is preserved.
13  * ====================================================
14  */
15 
16 #include "fdlibm.h"
17 
18 float
hypotf(float x,float y)19 hypotf(float x, float y)
20 {
21     float a = x, b = y, t1, t2, y1, y2, w;
22     __int32_t j, k, ha, hb;
23 
24     GET_FLOAT_WORD(ha, x);
25     ha &= 0x7fffffffL;
26     GET_FLOAT_WORD(hb, y);
27     hb &= 0x7fffffffL;
28     if (hb > ha) {
29         j = ha;
30         ha = hb;
31         hb = j;
32     }
33     SET_FLOAT_WORD(a, ha); /* a <- |a| */
34     SET_FLOAT_WORD(b, hb); /* b <- |b| */
35     if ((ha - hb) > 0xf000000L) {
36         return a + b;
37     } /* x/y > 2**30 */
38     k = 0;
39     if (ha > 0x58800000L) { /* a>2**50 */
40         if (!FLT_UWORD_IS_FINITE(ha)) { /* Inf or NaN */
41             w = a + b; /* for sNaN */
42             if (FLT_UWORD_IS_INFINITE(ha) && !issignaling(b))
43                 w = a;
44             if (FLT_UWORD_IS_INFINITE(hb) && !issignaling(a))
45                 w = b;
46             return w;
47         }
48         /* scale a and b by 2**-68 */
49         ha -= 0x22000000L;
50         hb -= 0x22000000L;
51         k += 68;
52         SET_FLOAT_WORD(a, ha);
53         SET_FLOAT_WORD(b, hb);
54     }
55     if (hb < 0x26800000L) { /* b < 2**-50 */
56         if (FLT_UWORD_IS_ZERO(hb)) {
57             return a;
58         } else if (FLT_UWORD_IS_SUBNORMAL(hb)) {
59             SET_FLOAT_WORD(t1, 0x7e800000L); /* t1=2^126 */
60             b *= t1;
61             a *= t1;
62             k -= 126;
63         } else { /* scale a and b by 2^68 */
64             ha += 0x22000000; /* a *= 2^68 */
65             hb += 0x22000000; /* b *= 2^68 */
66             k -= 68;
67             SET_FLOAT_WORD(a, ha);
68             SET_FLOAT_WORD(b, hb);
69         }
70     }
71     /* medium size a and b */
72     w = a - b;
73     if (w > b) {
74         SET_FLOAT_WORD(t1, ha & 0xfffff000L);
75         t2 = a - t1;
76         w = sqrtf(t1 * t1 - (b * (-b) - t2 * (a + t1)));
77     } else {
78         a = a + a;
79         SET_FLOAT_WORD(y1, hb & 0xfffff000L);
80         y2 = b - y1;
81         SET_FLOAT_WORD(t1, (ha + 0x00800000L) & 0xfffff000UL);
82         t2 = a - t1;
83         w = sqrtf(t1 * y1 - (w * (-w) - (t1 * y2 + t2 * b)));
84     }
85     if (k != 0) {
86         SET_FLOAT_WORD(t1, 0x3f800000L + (k << 23));
87         w *= t1;
88     }
89     return check_oflowf(w);
90 }
91 
92 _MATH_ALIAS_f_ff(hypot)
93