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