1 /*
2     Copyright (C) 2015 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 "arb.h"
13 
arb_eq(const arb_t x,const arb_t y)14 int arb_eq(const arb_t x, const arb_t y)
15 {
16     if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y)))
17         return 0;
18 
19     if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y)))
20         return 0;
21 
22     if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) ||
23         (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y))))
24         return arf_equal(arb_midref(x), arb_midref(y));
25 
26     return 0;
27 }
28 
arb_ne(const arb_t x,const arb_t y)29 int arb_ne(const arb_t x, const arb_t y)
30 {
31     if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y)))
32         return 0;
33 
34     if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y)))
35         return 0;
36 
37     if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) ||
38         (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y))))
39         return !arf_equal(arb_midref(x), arb_midref(y));
40 
41     return !arb_overlaps(x, y);
42 }
43 
arb_lt(const arb_t x,const arb_t y)44 int arb_lt(const arb_t x, const arb_t y)
45 {
46     arf_struct u[4];
47     arf_t t;
48     int res;
49 
50     if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y)))
51         return 0;
52 
53     if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y)))
54         return 0;
55 
56     if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) ||
57         (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y))))
58         return arf_cmp(arb_midref(x), arb_midref(y)) < 0;
59 
60     /* xm + xr < ym - yr  <=>  xm + xr - ym + yr < 0 */
61     arf_init_set_shallow(u + 0, arb_midref(x));
62     arf_init_neg_shallow(u + 1, arb_midref(y));
63     arf_init_set_mag_shallow(u + 2, arb_radref(x));
64     arf_init_set_mag_shallow(u + 3, arb_radref(y));
65 
66     arf_init(t);
67     arf_sum(t, u, 4, MAG_BITS, ARF_RND_DOWN);
68     res = (arf_sgn(t) < 0);
69     arf_clear(t);
70 
71     return res;
72 }
73 
arb_le(const arb_t x,const arb_t y)74 int arb_le(const arb_t x, const arb_t y)
75 {
76     arf_struct u[4];
77     arf_t t;
78     int res;
79 
80     if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y)))
81         return 0;
82 
83     if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y)))
84         return (arf_is_neg_inf(arb_midref(x)) && mag_is_finite(arb_radref(x)))
85             || (arf_is_pos_inf(arb_midref(y)) && mag_is_finite(arb_radref(y)));
86 
87     if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) ||
88         (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y))))
89         return arf_cmp(arb_midref(x), arb_midref(y)) <= 0;
90 
91     /* xm + xr <= ym - yr  <=>  xm + xr - ym + yr <= 0 */
92     arf_init_set_shallow(u + 0, arb_midref(x));
93     arf_init_neg_shallow(u + 1, arb_midref(y));
94     arf_init_set_mag_shallow(u + 2, arb_radref(x));
95     arf_init_set_mag_shallow(u + 3, arb_radref(y));
96 
97     arf_init(t);
98     arf_sum(t, u, 4, MAG_BITS, ARF_RND_DOWN);
99     res = (arf_sgn(t) <= 0);
100     arf_clear(t);
101 
102     return res;
103 }
104 
arb_gt(const arb_t x,const arb_t y)105 int arb_gt(const arb_t x, const arb_t y)
106 {
107     arf_struct u[4];
108     arf_t t;
109     int res;
110 
111     if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y)))
112         return 0;
113 
114     if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y)))
115         return 0;
116 
117     if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) ||
118         (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y))))
119         return arf_cmp(arb_midref(x), arb_midref(y)) > 0;
120 
121     /* xm - xr > ym + yr  <=>  xm - xr - ym - yr > 0 */
122     arf_init_set_shallow(u + 0, arb_midref(x));
123     arf_init_neg_shallow(u + 1, arb_midref(y));
124     arf_init_neg_mag_shallow(u + 2, arb_radref(x));
125     arf_init_neg_mag_shallow(u + 3, arb_radref(y));
126 
127     arf_init(t);
128     arf_sum(t, u, 4, MAG_BITS, ARF_RND_DOWN);
129     res = (arf_sgn(t) > 0);
130     arf_clear(t);
131 
132     return res;
133 }
134 
arb_ge(const arb_t x,const arb_t y)135 int arb_ge(const arb_t x, const arb_t y)
136 {
137     arf_struct u[4];
138     arf_t t;
139     int res;
140 
141     if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y)))
142         return 0;
143 
144     if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y)))
145         return (arf_is_pos_inf(arb_midref(x)) && mag_is_finite(arb_radref(x)))
146             || (arf_is_neg_inf(arb_midref(y)) && mag_is_finite(arb_radref(y)));
147 
148     if (arf_is_inf(arb_midref(x)) || arf_is_inf(arb_midref(y)) ||
149         (mag_is_zero(arb_radref(x)) && mag_is_zero(arb_radref(y))))
150         return arf_cmp(arb_midref(x), arb_midref(y)) >= 0;
151 
152     /* xm - xr >= ym + yr  <=>  xm - xr - ym - yr >= 0 */
153     arf_init_set_shallow(u + 0, arb_midref(x));
154     arf_init_neg_shallow(u + 1, arb_midref(y));
155     arf_init_neg_mag_shallow(u + 2, arb_radref(x));
156     arf_init_neg_mag_shallow(u + 3, arb_radref(y));
157 
158     arf_init(t);
159     arf_sum(t, u, 4, MAG_BITS, ARF_RND_DOWN);
160     res = (arf_sgn(t) >= 0);
161     arf_clear(t);
162 
163     return res;
164 }
165 
166 int
arb_contains_zero(const arb_t x)167 arb_contains_zero(const arb_t x)
168 {
169     return arf_cmpabs_mag(arb_midref(x), arb_radref(x)) <= 0;
170 }
171 
172 int
arb_is_nonzero(const arb_t x)173 arb_is_nonzero(const arb_t x)
174 {
175     return !arb_contains_zero(x);
176 }
177 
178 int
arb_is_positive(const arb_t x)179 arb_is_positive(const arb_t x)
180 {
181     return (arf_sgn(arb_midref(x)) > 0) &&
182         (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) < 0) &&
183          !arf_is_nan(arb_midref(x));
184 }
185 
186 int
arb_is_nonnegative(const arb_t x)187 arb_is_nonnegative(const arb_t x)
188 {
189     return (arf_sgn(arb_midref(x)) >= 0) &&
190         (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) <= 0) &&
191          !arf_is_nan(arb_midref(x));
192 }
193 
194 int
arb_is_negative(const arb_t x)195 arb_is_negative(const arb_t x)
196 {
197     return (arf_sgn(arb_midref(x)) < 0) &&
198         (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) < 0) &&
199          !arf_is_nan(arb_midref(x));
200 }
201 
202 int
arb_is_nonpositive(const arb_t x)203 arb_is_nonpositive(const arb_t x)
204 {
205     return (arf_sgn(arb_midref(x)) <= 0) &&
206         (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) <= 0) &&
207          !arf_is_nan(arb_midref(x));
208 }
209 
210 int
arb_contains_negative(const arb_t x)211 arb_contains_negative(const arb_t x)
212 {
213     return (arf_sgn(arb_midref(x)) < 0) ||
214         (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) > 0)
215         || arf_is_nan(arb_midref(x));
216 }
217 
218 int
arb_contains_nonpositive(const arb_t x)219 arb_contains_nonpositive(const arb_t x)
220 {
221     return (arf_sgn(arb_midref(x)) <= 0) ||
222         (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) >= 0)
223         || arf_is_nan(arb_midref(x));
224 }
225 
226 int
arb_contains_positive(const arb_t x)227 arb_contains_positive(const arb_t x)
228 {
229     return (arf_sgn(arb_midref(x)) > 0) ||
230         (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) > 0)
231         || arf_is_nan(arb_midref(x));
232 }
233 
234 int
arb_contains_nonnegative(const arb_t x)235 arb_contains_nonnegative(const arb_t x)
236 {
237     return (arf_sgn(arb_midref(x)) >= 0) ||
238         (arf_mag_cmpabs(arb_radref(x), arb_midref(x)) >= 0)
239         || arf_is_nan(arb_midref(x));
240 }
241 
242