1 /*
2     Copyright (C) 2014 Fredrik Johansson
3 
4     This file is part of Arb.
5 
6     Arb is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
10 */
11 
12 #include "acb.h"
13 
14 void
acb_div(acb_t z,const acb_t x,const acb_t y,slong prec)15 acb_div(acb_t z, const acb_t x, const acb_t y, slong prec)
16 {
17 #define a acb_realref(x)
18 #define b acb_imagref(x)
19 #define c acb_realref(y)
20 #define d acb_imagref(y)
21     if (arb_is_zero(d))
22     {
23         if (arb_is_zero(b))
24         {
25             arb_div(acb_realref(z), a, c, prec);
26             arb_zero(acb_imagref(z));
27         }
28         else if (arb_is_zero(a))
29         {
30             arb_div(acb_imagref(z), b, c, prec);
31             arb_zero(acb_realref(z));
32         }
33         else if (z != y)
34         {
35             arb_div(acb_realref(z), a, c, prec);
36             arb_div(acb_imagref(z), b, c, prec);
37         }
38         else
39         {
40             arb_t t;
41             arb_init(t);
42             arb_set(t, c);
43             arb_div(acb_realref(z), a, t, prec);
44             arb_div(acb_imagref(z), b, t, prec);
45             arb_clear(t);
46         }
47     }
48     else if (arb_is_zero(c))
49     {
50         if (arb_is_zero(b))
51         {
52             arb_div(acb_imagref(z), a, d, prec);
53             arb_neg(acb_imagref(z), acb_imagref(z));
54             arb_zero(acb_realref(z));
55         }
56         else if (arb_is_zero(a))
57         {
58             arb_div(acb_realref(z), b, d, prec);
59             arb_zero(acb_imagref(z));
60         }
61         else if (z != y)
62         {
63             arb_div(acb_realref(z), a, d, prec);
64             arb_div(acb_imagref(z), b, d, prec);
65             arb_swap(acb_realref(z), acb_imagref(z));
66             arb_neg(acb_imagref(z), acb_imagref(z));
67         }
68         else
69         {
70             arb_t t;
71             arb_init(t);
72             arb_set(t, d);
73             arb_div(acb_realref(z), a, t, prec);
74             arb_div(acb_imagref(z), b, t, prec);
75             arb_swap(acb_realref(z), acb_imagref(z));
76             arb_neg(acb_imagref(z), acb_imagref(z));
77             arb_clear(t);
78         }
79     }
80     else
81     {
82         if (prec > 256 && acb_bits(y) <= prec / 2 && acb_is_exact(y))
83         {
84             arb_t t, u, v;
85 
86             arb_init(t);
87             arb_init(u);
88             arb_init(v);
89 
90             arb_mul(t, c, c, prec);
91             arb_addmul(t, d, d, prec);
92 
93             arb_mul(u, a, c, prec);
94             arb_addmul(u, b, d, prec);
95 
96             arb_mul(v, b, c, prec);
97             arb_submul(v, a, d, prec);
98 
99             arb_div(acb_realref(z), u, t, prec);
100             arb_div(acb_imagref(z), v, t, prec);
101 
102             arb_clear(t);
103             arb_clear(u);
104             arb_clear(v);
105         }
106         else
107         {
108             acb_t t;
109             acb_init(t);
110             acb_inv(t, y, prec);
111             acb_mul(z, x, t, prec);
112             acb_clear(t);
113         }
114     }
115 #undef a
116 #undef b
117 #undef c
118 #undef d
119 }
120 
121