1 /* This file is distributed under the University of Illinois Open Source
2 * License. See LICENSE.TXT for details.
6 #include "../int_math.h"
8 #if !defined(CRT_INFINITY) && defined(HUGE_VAL)
9 #define CRT_INFINITY HUGE_VAL
10 #endif /* CRT_INFINITY */
12 #define makeFinite(x) { \
13 (x).s.hi = crt_copysign(crt_isinf((x).s.hi) ? 1.0 : 0.0, (x).s.hi); \
17 long double __gcc_qadd(long double, long double);
18 long double __gcc_qsub(long double, long double);
19 long double __gcc_qmul(long double, long double);
20 long double __gcc_qdiv(long double, long double);
23 __divtc3(long double a
, long double b
, long double c
, long double d
)
29 const double logbw
= crt_logb(crt_fmax(crt_fabs(cDD
.s
.hi
), crt_fabs(dDD
.s
.hi
) ));
31 if (crt_isfinite(logbw
))
35 cDD
.s
.hi
= crt_scalbn(cDD
.s
.hi
, -ilogbw
);
36 cDD
.s
.lo
= crt_scalbn(cDD
.s
.lo
, -ilogbw
);
37 dDD
.s
.hi
= crt_scalbn(dDD
.s
.hi
, -ilogbw
);
38 dDD
.s
.lo
= crt_scalbn(dDD
.s
.lo
, -ilogbw
);
41 const long double denom
= __gcc_qadd(__gcc_qmul(cDD
.ld
, cDD
.ld
), __gcc_qmul(dDD
.ld
, dDD
.ld
));
42 const long double realNumerator
= __gcc_qadd(__gcc_qmul(a
,cDD
.ld
), __gcc_qmul(b
,dDD
.ld
));
43 const long double imagNumerator
= __gcc_qsub(__gcc_qmul(b
,cDD
.ld
), __gcc_qmul(a
,dDD
.ld
));
45 DD real
= { .ld
= __gcc_qdiv(realNumerator
, denom
) };
46 DD imag
= { .ld
= __gcc_qdiv(imagNumerator
, denom
) };
48 real
.s
.hi
= crt_scalbn(real
.s
.hi
, -ilogbw
);
49 real
.s
.lo
= crt_scalbn(real
.s
.lo
, -ilogbw
);
50 imag
.s
.hi
= crt_scalbn(imag
.s
.hi
, -ilogbw
);
51 imag
.s
.lo
= crt_scalbn(imag
.s
.lo
, -ilogbw
);
53 if (crt_isnan(real
.s
.hi
) && crt_isnan(imag
.s
.hi
))
57 DD rDD
= { .ld
= denom
};
59 if ((rDD
.s
.hi
== 0.0) && (!crt_isnan(aDD
.s
.hi
) ||
60 !crt_isnan(bDD
.s
.hi
)))
62 real
.s
.hi
= crt_copysign(CRT_INFINITY
,cDD
.s
.hi
) * aDD
.s
.hi
;
64 imag
.s
.hi
= crt_copysign(CRT_INFINITY
,cDD
.s
.hi
) * bDD
.s
.hi
;
68 else if ((crt_isinf(aDD
.s
.hi
) || crt_isinf(bDD
.s
.hi
)) &&
69 crt_isfinite(cDD
.s
.hi
) && crt_isfinite(dDD
.s
.hi
))
73 real
.s
.hi
= CRT_INFINITY
* (aDD
.s
.hi
*cDD
.s
.hi
+ bDD
.s
.hi
*dDD
.s
.hi
);
75 imag
.s
.hi
= CRT_INFINITY
* (bDD
.s
.hi
*cDD
.s
.hi
- aDD
.s
.hi
*dDD
.s
.hi
);
79 else if ((crt_isinf(cDD
.s
.hi
) || crt_isinf(dDD
.s
.hi
)) &&
80 crt_isfinite(aDD
.s
.hi
) && crt_isfinite(bDD
.s
.hi
))
84 real
.s
.hi
= crt_copysign(0.0,(aDD
.s
.hi
*cDD
.s
.hi
+ bDD
.s
.hi
*dDD
.s
.hi
));
86 imag
.s
.hi
= crt_copysign(0.0,(bDD
.s
.hi
*cDD
.s
.hi
- aDD
.s
.hi
*dDD
.s
.hi
));
91 long double _Complex z
;