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