1 /* div.c: bcmath library file. */
2 /*
3 Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
4 Copyright (C) 2000 Philip A. Nelson
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details. (LICENSE)
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to:
18
19 The Free Software Foundation, Inc.
20 59 Temple Place, Suite 330
21 Boston, MA 02111-1307 USA.
22
23 You may contact the author by:
24 e-mail: philnelson@acm.org
25 us-mail: Philip A. Nelson
26 Computer Science Department, 9062
27 Western Washington University
28 Bellingham, WA 98226-9062
29
30 *************************************************************************/
31
32 #include "bcmath.h"
33 #include "private.h"
34 #include "convert.h"
35 #include <stdbool.h>
36 #include <stddef.h>
37 #include <string.h>
38 #include "zend_alloc.h"
39
40 static const BC_VECTOR POW_10_LUT[9] = {
41 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000
42 };
43
44 /*
45 * This function should be used when the divisor is not split into multiple chunks, i.e. when the size of the array is one.
46 * This is because the algorithm can be simplified.
47 * This function is therefore an optimized version of bc_standard_div().
48 */
bc_fast_div(BC_VECTOR * numerator_vectors,size_t numerator_arr_size,BC_VECTOR divisor_vector,BC_VECTOR * quot_vectors,size_t quot_arr_size)49 static inline void bc_fast_div(
50 BC_VECTOR *numerator_vectors, size_t numerator_arr_size, BC_VECTOR divisor_vector, BC_VECTOR *quot_vectors, size_t quot_arr_size)
51 {
52 size_t numerator_top_index = numerator_arr_size - 1;
53 size_t quot_top_index = quot_arr_size - 1;
54 for (size_t i = 0; i < quot_arr_size - 1; i++) {
55 if (numerator_vectors[numerator_top_index - i] < divisor_vector) {
56 quot_vectors[quot_top_index - i] = 0;
57 /* numerator_vectors[numerator_top_index - i] < divisor_vector, so there will be no overflow. */
58 numerator_vectors[numerator_top_index - i - 1] += numerator_vectors[numerator_top_index - i] * BC_VECTOR_BOUNDARY_NUM;
59 continue;
60 }
61 quot_vectors[quot_top_index - i] = numerator_vectors[numerator_top_index - i] / divisor_vector;
62 numerator_vectors[numerator_top_index - i] -= divisor_vector * quot_vectors[quot_top_index - i];
63 numerator_vectors[numerator_top_index - i - 1] += numerator_vectors[numerator_top_index - i] * BC_VECTOR_BOUNDARY_NUM;
64 numerator_vectors[numerator_top_index - i] = 0;
65 }
66 /* last */
67 quot_vectors[0] = numerator_vectors[0] / divisor_vector;
68 }
69
70 /*
71 * Used when the divisor is split into 2 or more chunks.
72 * This use the restoring division algorithm.
73 * https://en.wikipedia.org/wiki/Division_algorithm#Restoring_division
74 */
bc_standard_div(BC_VECTOR * numerator_vectors,size_t numerator_arr_size,BC_VECTOR * divisor_vectors,size_t divisor_arr_size,size_t divisor_len,BC_VECTOR * quot_vectors,size_t quot_arr_size)75 static inline void bc_standard_div(
76 BC_VECTOR *numerator_vectors, size_t numerator_arr_size,
77 BC_VECTOR *divisor_vectors, size_t divisor_arr_size, size_t divisor_len,
78 BC_VECTOR *quot_vectors, size_t quot_arr_size
79 ) {
80 size_t numerator_top_index = numerator_arr_size - 1;
81 size_t divisor_top_index = divisor_arr_size - 1;
82 size_t quot_top_index = quot_arr_size - 1;
83
84 BC_VECTOR div_carry = 0;
85
86 /*
87 * Errors might occur between the true quotient and the temporary quotient calculated using only the high order digits.
88 * For example, the true quotient of 240 / 121 is 1.
89 * However, if it is calculated using only the high-order digits (24 / 12), we would get 2.
90 * We refer to this value of 2 as the temporary quotient.
91 * We also define E to be error between the true quotient and the temporary quotient,
92 * which in this case, is 1.
93 *
94 * Another example: Calculating 999_0000_0000 / 1000_9999 with base 10000.
95 * The true quotient is 9980, but if it is calculated using only the high-order digits (999 / 1000), we would get 0
96 * If the temporary quotient is 0, we need to carry the digits to the next division, which is 999_0000 / 1000.
97 * The new temporary quotient we get is 9990, with error E = 10.
98 *
99 * Because we use the restoring division we need to perform E restorations, which can be significant if E is large.
100 *
101 * Therefore, for the error E to be at most 1 we adjust the number of high-order digits used to calculate the temporary quotient as follows:
102 * - Include BC_VECTOR_SIZE + 1 digits of the divisor used in the calculation of the temporary quotient.
103 The missing digits are filled in from the next array element.
104 * - Adjust the number of digits in the numerator similarly to what was done for the divisor.
105 *
106 * e.g.
107 * numerator = 123456780000
108 * divisor = 123456789
109 * base = 10000
110 * numerator_arr = [0, 5678, 1234]
111 * divisor_arr = [6789, 2345, 1]
112 * numerator_top = 1234
113 * divisor_top = 1
114 * divisor_top_tmp = 12345 (+4 digits)
115 * numerator_top_tmp = 12345678 (+4 digits)
116 * tmp_quot = numerator_top_tmp / divisor_top_tmp = 1000
117 * tmp_rem = -9000
118 * tmp_quot is too large, so tmp_quot--, tmp_rem += divisor (restoring)
119 * quot = 999
120 * rem = 123447789
121 *
122 * Details:
123 * Suppose that when calculating the temporary quotient, only the high-order elements of the BC_VECTOR array are used.
124 * At this time, numerator and divisor can be considered to be decomposed as follows. (Here, B = 10^b, any b ∈ ℕ, any k ∈ ℕ)
125 * numerator = numerator_high * B^k + numerator_low
126 * divisor = divisor_high * B^k + divisor_low
127 *
128 * The error E can be expressed by the following formula.
129 *
130 * E = (numerator_high * B^k) / (divisor_high * B^k) - (numerator_high * B^k + numerator_low) / (divisor_high * B^k + divisor_low)
131 * <=> E = numerator_high / divisor_high - (numerator_high * B^k + numerator_low) / (divisor_high * B^k + divisor_low)
132 * <=> E = (numerator_high * (divisor_high * B^k + divisor_low) - (numerator_high * B^k + numerator_low) * divisor_high) / (divisor_high * (divisor_high * B^k + divisor_low))
133 * <=> E = (numerator_high * divisor_low - divisor_high * numerator_low) / (divisor_high * (divisor_high * B^k + divisor_low))
134 *
135 * Find the error MAX_E when the error E is maximum (0 <= E <= MAX_E).
136 * First, numerator_high, which only exists in the numerator, uses its maximum value.
137 * Considering carry-back, numerator_high can be expressed as follows.
138 * numerator_high = divisor_high * B
139 * Also, numerator_low is only present in the numerator, but since this is a subtraction, use the smallest possible value here, 0.
140 * numerator_low = 0
141 *
142 * MAX_E = (numerator_high * divisor_low - divisor_high * numerator_low) / (divisor_high * (divisor_high * B^k + divisor_low))
143 * <=> MAX_E = (divisor_high * B * divisor_low) / (divisor_high * (divisor_high * B^k + divisor_low))
144 *
145 * divisor_low uses the maximum value.
146 * divisor_low = B^k - 1
147 * MAX_E = (divisor_high * B * divisor_low) / (divisor_high * (divisor_high * B^k + divisor_low))
148 * <=> MAX_E = (divisor_high * B * (B^k - 1)) / (divisor_high * (divisor_high * B^k + B^k - 1))
149 *
150 * divisor_high uses the minimum value, but want to see how the number of digits affects the error, so represent
151 * the minimum value as:
152 * divisor_high = 10^x (any x ∈ ℕ)
153 * Since B = 10^b, the formula becomes:
154 * MAX_E = (divisor_high * B * (B^k - 1)) / (divisor_high * (divisor_high * B^k + B^k - 1))
155 * <=> MAX_E = (10^x * 10^b * ((10^b)^k - 1)) / (10^x * (10^x * (10^b)^k + (10^b)^k - 1))
156 *
157 * Now let's make an approximation. Remove -1 from the numerator. Approximate the numerator to be
158 * large and the denominator to be small, such that MAX_E is less than this expression.
159 * Also, the denominator "(10^b)^k - 1" is never a negative value, so delete it.
160 *
161 * MAX_E = (10^x * 10^b * ((10^b)^k - 1)) / (10^x * (10^x * (10^b)^k + (10^b)^k - 1))
162 * MAX_E < (10^x * 10^b * (10^b)^k) / (10^x * 10^x * (10^b)^k)
163 * <=> MAX_E < 10^b / 10^x
164 * <=> MAX_E < 10^(b - x)
165 *
166 * Therefore, found that if the number of digits in base B and divisor_high are equal, the error will be less
167 * than 1 regardless of the number of digits in the value of k.
168 *
169 * Here, B is BC_VECTOR_BOUNDARY_NUM, so adjust the number of digits in high part of divisor to be BC_VECTOR_SIZE + 1.
170 */
171 /* the number of usable digits, thus divisor_len % BC_VECTOR_SIZE == 0 implies we have BC_VECTOR_SIZE usable digits */
172 size_t divisor_top_digits = divisor_len % BC_VECTOR_SIZE;
173 if (divisor_top_digits == 0) {
174 divisor_top_digits = BC_VECTOR_SIZE;
175 }
176
177 size_t high_part_shift = POW_10_LUT[BC_VECTOR_SIZE - divisor_top_digits + 1];
178 size_t low_part_shift = POW_10_LUT[divisor_top_digits - 1];
179 BC_VECTOR divisor_high_part = divisor_vectors[divisor_top_index] * high_part_shift + divisor_vectors[divisor_top_index - 1] / low_part_shift;
180 for (size_t i = 0; i < quot_arr_size; i++) {
181 BC_VECTOR numerator_high_part = numerator_vectors[numerator_top_index - i] * high_part_shift + numerator_vectors[numerator_top_index - i - 1] / low_part_shift;
182
183 /*
184 * Determine the temporary quotient.
185 * The maximum value of numerator_high is divisor_high * B in the previous example, so here numerator_high_part is
186 * divisor_high_part * BC_VECTOR_BOUNDARY_NUM.
187 * The number of digits in divisor_high_part is BC_VECTOR_SIZE + 1, so even if divisor_high_part is at its maximum value,
188 * it will never overflow here.
189 */
190 numerator_high_part += div_carry * BC_VECTOR_BOUNDARY_NUM * high_part_shift;
191
192 /* numerator_high_part < divisor_high_part => quotient == 0 */
193 if (numerator_high_part < divisor_high_part) {
194 quot_vectors[quot_top_index - i] = 0;
195 div_carry = numerator_vectors[numerator_top_index - i];
196 numerator_vectors[numerator_top_index - i] = 0;
197 continue;
198 }
199
200 BC_VECTOR quot_guess = numerator_high_part / divisor_high_part;
201
202 /* For sub, add the remainder to the high-order digit */
203 numerator_vectors[numerator_top_index - i] += div_carry * BC_VECTOR_BOUNDARY_NUM;
204
205 /*
206 * It is impossible for the temporary quotient to underestimate the true quotient.
207 * Therefore a temporary quotient of 0 implies the true quotient is also 0.
208 */
209 if (quot_guess == 0) {
210 quot_vectors[quot_top_index - i] = 0;
211 div_carry = numerator_vectors[numerator_top_index - i];
212 numerator_vectors[numerator_top_index - i] = 0;
213 continue;
214 }
215
216 /* sub */
217 BC_VECTOR sub;
218 BC_VECTOR borrow = 0;
219 BC_VECTOR *numerator_calc_bottom = numerator_vectors + numerator_arr_size - divisor_arr_size - i;
220 size_t j;
221 for (j = 0; j < divisor_arr_size - 1; j++) {
222 sub = divisor_vectors[j] * quot_guess + borrow;
223 BC_VECTOR sub_low = sub % BC_VECTOR_BOUNDARY_NUM;
224 borrow = sub / BC_VECTOR_BOUNDARY_NUM;
225
226 if (numerator_calc_bottom[j] >= sub_low) {
227 numerator_calc_bottom[j] -= sub_low;
228 } else {
229 numerator_calc_bottom[j] += BC_VECTOR_BOUNDARY_NUM - sub_low;
230 borrow++;
231 }
232 }
233 /* last digit sub */
234 sub = divisor_vectors[j] * quot_guess + borrow;
235 bool neg_remainder = numerator_calc_bottom[j] < sub;
236 numerator_calc_bottom[j] -= sub;
237
238 /* If the temporary quotient is too large, add back divisor */
239 BC_VECTOR carry = 0;
240 if (neg_remainder) {
241 quot_guess--;
242 for (j = 0; j < divisor_arr_size - 1; j++) {
243 numerator_calc_bottom[j] += divisor_vectors[j] + carry;
244 carry = numerator_calc_bottom[j] / BC_VECTOR_BOUNDARY_NUM;
245 numerator_calc_bottom[j] %= BC_VECTOR_BOUNDARY_NUM;
246 }
247 /* last add */
248 numerator_calc_bottom[j] += divisor_vectors[j] + carry;
249 }
250
251 quot_vectors[quot_top_index - i] = quot_guess;
252 div_carry = numerator_vectors[numerator_top_index - i];
253 numerator_vectors[numerator_top_index - i] = 0;
254 }
255 }
256
bc_do_div(const char * numerator,size_t numerator_readable_len,size_t numerator_bottom_extension,const char * divisor,size_t divisor_len,bc_num * quot,size_t quot_len)257 static void bc_do_div(
258 const char *numerator, size_t numerator_readable_len, size_t numerator_bottom_extension,
259 const char *divisor, size_t divisor_len, bc_num *quot, size_t quot_len
260 ) {
261 size_t divisor_arr_size = (divisor_len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
262 size_t numerator_arr_size = (numerator_readable_len + numerator_bottom_extension + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
263 size_t quot_arr_size = numerator_arr_size - divisor_arr_size + 1;
264 size_t quot_real_arr_size = MIN(quot_arr_size, (quot_len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE);
265
266 BC_VECTOR *numerator_vectors = safe_emalloc(numerator_arr_size + divisor_arr_size + quot_arr_size, sizeof(BC_VECTOR), 0);
267 BC_VECTOR *divisor_vectors = numerator_vectors + numerator_arr_size;
268 BC_VECTOR *quot_vectors = divisor_vectors + divisor_arr_size;
269
270 /* Fill with zeros and convert as many vector elements as needed */
271 size_t numerator_vector_count = 0;
272 while (numerator_bottom_extension >= BC_VECTOR_SIZE) {
273 numerator_vectors[numerator_vector_count] = 0;
274 numerator_bottom_extension -= BC_VECTOR_SIZE;
275 numerator_vector_count++;
276 }
277
278 size_t numerator_bottom_read_len = BC_VECTOR_SIZE - numerator_bottom_extension;
279
280 size_t base;
281 size_t numerator_read = 0;
282 if (numerator_bottom_read_len < BC_VECTOR_SIZE) {
283 numerator_read = MIN(numerator_bottom_read_len, numerator_readable_len);
284 base = POW_10_LUT[numerator_bottom_extension];
285 numerator_vectors[numerator_vector_count] = 0;
286 for (size_t i = 0; i < numerator_read; i++) {
287 numerator_vectors[numerator_vector_count] += *numerator * base;
288 base *= BASE;
289 numerator--;
290 }
291 numerator_vector_count++;
292 }
293
294 /* Bulk convert numerator and divisor to vectors */
295 if (numerator_readable_len > numerator_read) {
296 bc_convert_to_vector(numerator_vectors + numerator_vector_count, numerator, numerator_readable_len - numerator_read);
297 }
298 bc_convert_to_vector(divisor_vectors, divisor, divisor_len);
299
300 /* Do the division */
301 if (divisor_arr_size == 1) {
302 bc_fast_div(numerator_vectors, numerator_arr_size, divisor_vectors[0], quot_vectors, quot_arr_size);
303 } else {
304 bc_standard_div(numerator_vectors, numerator_arr_size, divisor_vectors, divisor_arr_size, divisor_len, quot_vectors, quot_arr_size);
305 }
306
307 /* Convert to bc_num */
308 char *qptr = (*quot)->n_value;
309 char *qend = qptr + quot_len - 1;
310
311 size_t i;
312 for (i = 0; i < quot_real_arr_size - 1; i++) {
313 #if BC_VECTOR_SIZE == 4
314 bc_write_bcd_representation(quot_vectors[i], qend - 3);
315 qend -= 4;
316 #else
317 bc_write_bcd_representation(quot_vectors[i] / 10000, qend - 7);
318 bc_write_bcd_representation(quot_vectors[i] % 10000, qend - 3);
319 qend -= 8;
320 #endif
321 }
322
323 while (qend >= qptr) {
324 *qend-- = quot_vectors[i] % BASE;
325 quot_vectors[i] /= BASE;
326 }
327
328 efree(numerator_vectors);
329 }
330
bc_divide(bc_num numerator,bc_num divisor,bc_num * quot,size_t scale)331 bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale)
332 {
333 /* divide by zero */
334 if (bc_is_zero(divisor)) {
335 return false;
336 }
337
338 bc_free_num(quot);
339
340 /* If numerator is zero, the quotient is always zero. */
341 if (bc_is_zero(numerator)) {
342 *quot = bc_copy_num(BCG(_zero_));
343 return true;
344 }
345
346 /* If divisor is 1 / -1, the quotient's n_value is equal to numerator's n_value. */
347 if (_bc_do_compare(divisor, BCG(_one_), divisor->n_scale, false) == BCMATH_EQUAL) {
348 size_t quot_scale = MIN(numerator->n_scale, scale);
349 *quot = bc_new_num_nonzeroed(numerator->n_len, quot_scale);
350 char *qptr = (*quot)->n_value;
351 memcpy(qptr, numerator->n_value, numerator->n_len + quot_scale);
352 (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS;
353 _bc_rm_leading_zeros(*quot);
354 return true;
355 }
356
357 char *numeratorptr = numerator->n_value;
358 char *numeratorend = numeratorptr + numerator->n_len + numerator->n_scale - 1;
359 size_t numerator_len = numerator->n_len;
360 size_t numerator_scale = numerator->n_scale;
361
362 char *divisorptr = divisor->n_value;
363 char *divisorend = divisorptr + divisor->n_len + divisor->n_scale - 1;
364 size_t divisor_len = divisor->n_len;
365 size_t divisor_scale = divisor->n_scale;
366 size_t divisor_int_right_zeros = 0;
367
368 /* remove divisor trailing zeros */
369 while (*divisorend == 0 && divisor_scale > 0) {
370 divisorend--;
371 divisor_scale--;
372 }
373 while (*divisorend == 0) {
374 divisorend--;
375 divisor_int_right_zeros++;
376 }
377
378 if (*numeratorptr == 0 && numerator_len == 1) {
379 numeratorptr++;
380 numerator_len = 0;
381 }
382
383 size_t numerator_top_extension = 0;
384 size_t numerator_bottom_extension = 0;
385 if (divisor_scale > 0) {
386 /*
387 * e.g. divisor_scale = 4
388 * divisor = .0002, to be 2 or divisor = 200.001, to be 200001
389 * numerator = .03, to be 300 or numerator = .000003, to be .03
390 * numerator may become longer than the original data length due to the addition of
391 * trailing zeros in the integer part.
392 */
393 numerator_len += divisor_scale;
394 numerator_bottom_extension = numerator_scale < divisor_scale ? divisor_scale - numerator_scale : 0;
395 numerator_scale = numerator_scale > divisor_scale ? numerator_scale - divisor_scale : 0;
396 divisor_len += divisor_scale;
397 divisor_scale = 0;
398 } else if (divisor_int_right_zeros > 0) {
399 /*
400 * e.g. divisor_int_right_zeros = 4
401 * divisor = 2000, to be 2
402 * numerator = 30, to be .03 or numerator = 30000, to be 30
403 * Also, numerator may become longer than the original data length due to the addition of
404 * leading zeros in the fractional part.
405 */
406 numerator_top_extension = numerator_len < divisor_int_right_zeros ? divisor_int_right_zeros - numerator_len : 0;
407 numerator_len = numerator_len > divisor_int_right_zeros ? numerator_len - divisor_int_right_zeros : 0;
408 numerator_scale += divisor_int_right_zeros;
409 divisor_len -= divisor_int_right_zeros;
410 divisor_scale = 0;
411 }
412
413 /* remove numerator leading zeros */
414 while (*numeratorptr == 0 && numerator_len > 0) {
415 numeratorptr++;
416 numerator_len--;
417 }
418 /* remove divisor leading zeros */
419 while (*divisorptr == 0) {
420 divisorptr++;
421 divisor_len--;
422 }
423
424 /* Considering the scale specification, the quotient is always 0 if this condition is met */
425 if (divisor_len > numerator_len + scale) {
426 *quot = bc_copy_num(BCG(_zero_));
427 return true;
428 }
429
430 /* set scale to numerator */
431 if (numerator_scale > scale) {
432 size_t scale_diff = numerator_scale - scale;
433 if (numerator_bottom_extension > scale_diff) {
434 numerator_bottom_extension -= scale_diff;
435 } else {
436 numerator_bottom_extension = 0;
437 numeratorend -= scale_diff > numerator_top_extension ? scale_diff - numerator_top_extension : 0;
438 }
439 } else {
440 numerator_bottom_extension += scale - numerator_scale;
441 }
442 numerator_scale = scale;
443
444 /* Length of numerator data that can be read */
445 size_t numerator_readable_len = numeratorend - numeratorptr + 1;
446
447 if (divisor_len > numerator_readable_len + numerator_bottom_extension) {
448 *quot = bc_copy_num(BCG(_zero_));
449 return true;
450 }
451
452 /* If divisor is 1 here, return the result of adjusting the decimal point position of numerator. */
453 if (divisor_len == 1 && *divisorptr == 1) {
454 if (numerator_len == 0) {
455 numerator_len = 1;
456 numerator_top_extension++;
457 }
458 size_t quot_scale = numerator_scale > numerator_bottom_extension ? numerator_scale - numerator_bottom_extension : 0;
459 numerator_bottom_extension = numerator_scale < numerator_bottom_extension ? numerator_bottom_extension - numerator_scale : 0;
460
461 *quot = bc_new_num_nonzeroed(numerator_len, quot_scale);
462 char *qptr = (*quot)->n_value;
463 for (size_t i = 0; i < numerator_top_extension; i++) {
464 *qptr++ = 0;
465 }
466 memcpy(qptr, numeratorptr, numerator_readable_len);
467 qptr += numerator_readable_len;
468 for (size_t i = 0; i < numerator_bottom_extension; i++) {
469 *qptr++ = 0;
470 }
471 (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS;
472 return true;
473 }
474
475 size_t quot_full_len;
476 if (divisor_len > numerator_len) {
477 *quot = bc_new_num_nonzeroed(1, scale);
478 quot_full_len = 1 + scale;
479 } else {
480 *quot = bc_new_num_nonzeroed(numerator_len - divisor_len + 1, scale);
481 quot_full_len = numerator_len - divisor_len + 1 + scale;
482 }
483
484 /* do divide */
485 bc_do_div(numeratorend, numerator_readable_len, numerator_bottom_extension, divisorend, divisor_len, quot, quot_full_len);
486 _bc_rm_leading_zeros(*quot);
487 if (bc_is_zero(*quot)) {
488 (*quot)->n_sign = PLUS;
489 } else {
490 (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS;
491 }
492
493 return true;
494 }
495