aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-18 12:23:16 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-18 12:23:16 +0100
commite2e6ffd3c5e229ef386ca22e467c6553e570c55a (patch)
tree66f84838853fb7616cabe3eb5d53ac563e48e9e8
parent4113e1f2cd2f45a95bcb0920bf2e3ee75b906281 (diff)
downloadbusybox-w32-e2e6ffd3c5e229ef386ca22e467c6553e570c55a.tar.gz
busybox-w32-e2e6ffd3c5e229ef386ca22e467c6553e570c55a.tar.bz2
busybox-w32-e2e6ffd3c5e229ef386ca22e467c6553e570c55a.zip
bc: replace signed division / 10 by unsigned
function old new delta zbc_num_a 443 441 -2 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c93
1 files changed, 32 insertions, 61 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index eaab6cee6..6c63c1703 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -1466,9 +1466,10 @@ static void bc_num_subArrays(BcDig *restrict a, BcDig *restrict b,
1466{ 1466{
1467 size_t i, j; 1467 size_t i, j;
1468 for (i = 0; i < len; ++i) { 1468 for (i = 0; i < len; ++i) {
1469 for (a[i] -= b[i], j = 0; a[i + j] < 0;) { 1469 a[i] -= b[i];
1470 a[i + j++] += 10; 1470 for (j = i; a[j] < 0;) {
1471 a[i + j] -= 1; 1471 a[j++] += 10;
1472 a[j] -= 1;
1472 } 1473 }
1473 } 1474 }
1474} 1475}
@@ -1647,7 +1648,7 @@ static FAST_FUNC BC_STATUS zbc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size
1647{ 1648{
1648 BcDig *ptr, *ptr_a, *ptr_b, *ptr_c; 1649 BcDig *ptr, *ptr_a, *ptr_b, *ptr_c;
1649 size_t i, max, min_rdx, min_int, diff, a_int, b_int; 1650 size_t i, max, min_rdx, min_int, diff, a_int, b_int;
1650 int carry, in; 1651 unsigned carry;
1651 1652
1652 // Because this function doesn't need to use scale (per the bc spec), 1653 // Because this function doesn't need to use scale (per the bc spec),
1653 // I am hijacking it to say whether it's doing an add or a subtract. 1654 // I am hijacking it to say whether it's doing an add or a subtract.
@@ -1672,15 +1673,16 @@ static FAST_FUNC BC_STATUS zbc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size
1672 ptr = a->num; 1673 ptr = a->num;
1673 ptr_a = a->num + diff; 1674 ptr_a = a->num + diff;
1674 ptr_b = b->num; 1675 ptr_b = b->num;
1675 } 1676 } else {
1676 else {
1677 diff = b->rdx - a->rdx; 1677 diff = b->rdx - a->rdx;
1678 ptr = b->num; 1678 ptr = b->num;
1679 ptr_a = a->num; 1679 ptr_a = a->num;
1680 ptr_b = b->num + diff; 1680 ptr_b = b->num + diff;
1681 } 1681 }
1682 1682
1683 for (ptr_c = c->num, i = 0; i < diff; ++i, ++c->len) ptr_c[i] = ptr[i]; 1683 ptr_c = c->num;
1684 for (i = 0; i < diff; ++i, ++c->len)
1685 ptr_c[i] = ptr[i];
1684 1686
1685 ptr_c += diff; 1687 ptr_c += diff;
1686 a_int = BC_NUM_INT(a); 1688 a_int = BC_NUM_INT(a);
@@ -1690,24 +1692,24 @@ static FAST_FUNC BC_STATUS zbc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size
1690 min_int = b_int; 1692 min_int = b_int;
1691 max = a_int; 1693 max = a_int;
1692 ptr = ptr_a; 1694 ptr = ptr_a;
1693 } 1695 } else {
1694 else {
1695 min_int = a_int; 1696 min_int = a_int;
1696 max = b_int; 1697 max = b_int;
1697 ptr = ptr_b; 1698 ptr = ptr_b;
1698 } 1699 }
1699 1700
1700 for (carry = 0, i = 0; i < min_rdx + min_int; ++i, ++c->len) { 1701 carry = 0;
1701 in = ((int) ptr_a[i]) + ((int) ptr_b[i]) + carry; 1702 for (i = 0; i < min_rdx + min_int; ++i) {
1703 unsigned in = (unsigned)ptr_a[i] + (unsigned)ptr_b[i] + carry;
1702 carry = in / 10; 1704 carry = in / 10;
1703 ptr_c[i] = (BcDig)(in % 10); 1705 ptr_c[i] = (BcDig)(in % 10);
1704 } 1706 }
1705 1707 for (; i < max + min_rdx; ++i) {
1706 for (; i < max + min_rdx; ++i, ++c->len) { 1708 unsigned in = (unsigned)ptr[i] + carry;
1707 in = ((int) ptr[i]) + carry;
1708 carry = in / 10; 1709 carry = in / 10;
1709 ptr_c[i] = (BcDig)(in % 10); 1710 ptr_c[i] = (BcDig)(in % 10);
1710 } 1711 }
1712 c->len += i;
1711 1713
1712 if (carry != 0) c->num[c->len++] = (BcDig) carry; 1714 if (carry != 0) c->num[c->len++] = (BcDig) carry;
1713 1715
@@ -1751,8 +1753,7 @@ static FAST_FUNC BC_STATUS zbc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size
1751 neg = a->neg; 1753 neg = a->neg;
1752 minuend = a; 1754 minuend = a;
1753 subtrahend = b; 1755 subtrahend = b;
1754 } 1756 } else {
1755 else {
1756 neg = b->neg; 1757 neg = b->neg;
1757 if (sub) neg = !neg; 1758 if (sub) neg = !neg;
1758 minuend = b; 1759 minuend = b;
@@ -1765,8 +1766,7 @@ static FAST_FUNC BC_STATUS zbc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size
1765 if (c->rdx < subtrahend->rdx) { 1766 if (c->rdx < subtrahend->rdx) {
1766 bc_num_extend(c, subtrahend->rdx - c->rdx); 1767 bc_num_extend(c, subtrahend->rdx - c->rdx);
1767 start = 0; 1768 start = 0;
1768 } 1769 } else
1769 else
1770 start = c->rdx - subtrahend->rdx; 1770 start = c->rdx - subtrahend->rdx;
1771 1771
1772 bc_num_subArrays(c->num + start, subtrahend->num, subtrahend->len); 1772 bc_num_subArrays(c->num + start, subtrahend->num, subtrahend->len);
@@ -1795,11 +1795,11 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
1795 RETURN_STATUS(BC_STATUS_SUCCESS); 1795 RETURN_STATUS(BC_STATUS_SUCCESS);
1796 } 1796 }
1797 1797
1798 if (a->len + b->len < BC_NUM_KARATSUBA_LEN || 1798 if (a->len + b->len < BC_NUM_KARATSUBA_LEN
1799 a->len < BC_NUM_KARATSUBA_LEN || b->len < BC_NUM_KARATSUBA_LEN) 1799 || a->len < BC_NUM_KARATSUBA_LEN
1800 { 1800 || b->len < BC_NUM_KARATSUBA_LEN
1801 ) {
1801 size_t i, j, len; 1802 size_t i, j, len;
1802 unsigned carry;
1803 1803
1804 bc_num_expand(c, a->len + b->len + 1); 1804 bc_num_expand(c, a->len + b->len + 1);
1805 1805
@@ -1807,11 +1807,10 @@ static FAST_FUNC BC_STATUS zbc_num_k(BcNum *restrict a, BcNum *restrict b,
1807 c->len = len = 0; 1807 c->len = len = 0;
1808 1808
1809 for (i = 0; i < b->len; ++i) { 1809 for (i = 0; i < b->len; ++i) {
1810 1810 unsigned carry = 0;
1811 carry = 0;
1812 for (j = 0; j < a->len; ++j) { 1811 for (j = 0; j < a->len; ++j) {
1813 unsigned in = c->num[i + j]; 1812 unsigned in = c->num[i + j];
1814 in += ((unsigned) a->num[j]) * ((unsigned) b->num[i]) + carry; 1813 in += (unsigned)a->num[j] * (unsigned)b->num[i] + carry;
1815 // note: compilers prefer _unsigned_ div/const 1814 // note: compilers prefer _unsigned_ div/const
1816 carry = in / 10; 1815 carry = in / 10;
1817 c->num[i + j] = (BcDig)(in % 10); 1816 c->num[i + j] = (BcDig)(in % 10);
@@ -2158,8 +2157,7 @@ static BC_STATUS zbc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale,
2158 ptr_a = &num2; 2157 ptr_a = &num2;
2159 memcpy(ptr_a, c, sizeof(BcNum)); 2158 memcpy(ptr_a, c, sizeof(BcNum));
2160 init = true; 2159 init = true;
2161 } 2160 } else
2162 else
2163 ptr_a = a; 2161 ptr_a = a;
2164 2162
2165 if (c == b) { 2163 if (c == b) {
@@ -2168,8 +2166,7 @@ static BC_STATUS zbc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale,
2168 memcpy(ptr_b, c, sizeof(BcNum)); 2166 memcpy(ptr_b, c, sizeof(BcNum));
2169 init = true; 2167 init = true;
2170 } 2168 }
2171 } 2169 } else
2172 else
2173 ptr_b = b; 2170 ptr_b = b;
2174 2171
2175 if (init) 2172 if (init)
@@ -2350,10 +2347,9 @@ static BC_STATUS zbc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale)
2350 if (a->len == 0) { 2347 if (a->len == 0) {
2351 bc_num_setToZero(b, scale); 2348 bc_num_setToZero(b, scale);
2352 RETURN_STATUS(BC_STATUS_SUCCESS); 2349 RETURN_STATUS(BC_STATUS_SUCCESS);
2353 } 2350 } else if (a->neg) {
2354 else if (a->neg)
2355 RETURN_STATUS(bc_error("negative number")); 2351 RETURN_STATUS(bc_error("negative number"));
2356 else if (BC_NUM_ONE(a)) { 2352 } else if (BC_NUM_ONE(a)) {
2357 bc_num_one(b); 2353 bc_num_one(b);
2358 bc_num_extend(b, scale); 2354 bc_num_extend(b, scale);
2359 RETURN_STATUS(BC_STATUS_SUCCESS); 2355 RETURN_STATUS(BC_STATUS_SUCCESS);
@@ -2380,7 +2376,6 @@ static BC_STATUS zbc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale)
2380 pow = BC_NUM_INT(a); 2376 pow = BC_NUM_INT(a);
2381 2377
2382 if (pow) { 2378 if (pow) {
2383
2384 if (pow & 1) 2379 if (pow & 1)
2385 x0->num[0] = 2; 2380 x0->num[0] = 2;
2386 else 2381 else
@@ -2399,7 +2394,6 @@ static BC_STATUS zbc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale)
2399 len = BC_NUM_INT(x0) + resrdx - 1; 2394 len = BC_NUM_INT(x0) + resrdx - 1;
2400 2395
2401 while (cmp != 0 || digs < len) { 2396 while (cmp != 0 || digs < len) {
2402
2403 s = zbc_num_div(a, x0, &f, resrdx); 2397 s = zbc_num_div(a, x0, &f, resrdx);
2404 if (s) goto err; 2398 if (s) goto err;
2405 s = zbc_num_add(x0, &f, &fprime, resrdx); 2399 s = zbc_num_add(x0, &f, &fprime, resrdx);
@@ -2429,8 +2423,7 @@ static BC_STATUS zbc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale)
2429 bc_num_copy(b, x0); 2423 bc_num_copy(b, x0);
2430 scale -= 1; 2424 scale -= 1;
2431 if (b->rdx > scale) bc_num_truncate(b, b->rdx - scale); 2425 if (b->rdx > scale) bc_num_truncate(b, b->rdx - scale);
2432 2426 err:
2433err:
2434 bc_num_free(&fprime); 2427 bc_num_free(&fprime);
2435 bc_num_free(&f); 2428 bc_num_free(&f);
2436 bc_num_free(&half); 2429 bc_num_free(&half);
@@ -2453,8 +2446,7 @@ static BC_STATUS zbc_num_divmod(BcNum *a, BcNum *b, BcNum *c, BcNum *d,
2453 ptr_a = &num2; 2446 ptr_a = &num2;
2454 bc_num_init(c, len); 2447 bc_num_init(c, len);
2455 init = true; 2448 init = true;
2456 } 2449 } else {
2457 else {
2458 ptr_a = a; 2450 ptr_a = a;
2459 bc_num_expand(c, len); 2451 bc_num_expand(c, len);
2460 } 2452 }
@@ -2495,7 +2487,6 @@ static BC_STATUS zbc_num_modexp(BcNum *a, BcNum *b, BcNum *c, BcNum *restrict d)
2495 bc_num_copy(&exp, b); 2487 bc_num_copy(&exp, b);
2496 2488
2497 while (exp.len != 0) { 2489 while (exp.len != 0) {
2498
2499 s = zbc_num_divmod(&exp, &two, &exp, &temp, 0); 2490 s = zbc_num_divmod(&exp, &two, &exp, &temp, 0);
2500 if (s) goto err; 2491 if (s) goto err;
2501 2492
@@ -2511,8 +2502,7 @@ static BC_STATUS zbc_num_modexp(BcNum *a, BcNum *b, BcNum *c, BcNum *restrict d)
2511 s = zbc_num_rem(&temp, c, &base, 0); 2502 s = zbc_num_rem(&temp, c, &base, 0);
2512 if (s) goto err; 2503 if (s) goto err;
2513 } 2504 }
2514 2505 err:
2515err:
2516 bc_num_free(&temp); 2506 bc_num_free(&temp);
2517 bc_num_free(&two); 2507 bc_num_free(&two);
2518 bc_num_free(&exp); 2508 bc_num_free(&exp);
@@ -2579,8 +2569,7 @@ static void bc_array_expand(BcVec *a, size_t len)
2579 bc_num_init_DEF_SIZE(&data.n); 2569 bc_num_init_DEF_SIZE(&data.n);
2580 bc_vec_push(a, &data.n); 2570 bc_vec_push(a, &data.n);
2581 } 2571 }
2582 } 2572 } else {
2583 else {
2584 while (len > a->len) { 2573 while (len > a->len) {
2585 bc_array_init(&data.v, true); 2574 bc_array_init(&data.v, true);
2586 bc_vec_push(a, &data.v); 2575 bc_vec_push(a, &data.v);
@@ -2614,33 +2603,24 @@ static void bc_result_copy(BcResult *d, BcResult *src)
2614 d->t = src->t; 2603 d->t = src->t;
2615 2604
2616 switch (d->t) { 2605 switch (d->t) {
2617
2618 case BC_RESULT_TEMP: 2606 case BC_RESULT_TEMP:
2619 case BC_RESULT_IBASE: 2607 case BC_RESULT_IBASE:
2620 case BC_RESULT_SCALE: 2608 case BC_RESULT_SCALE:
2621 case BC_RESULT_OBASE: 2609 case BC_RESULT_OBASE:
2622 {
2623 bc_num_init(&d->d.n, src->d.n.len); 2610 bc_num_init(&d->d.n, src->d.n.len);
2624 bc_num_copy(&d->d.n, &src->d.n); 2611 bc_num_copy(&d->d.n, &src->d.n);
2625 break; 2612 break;
2626 }
2627
2628 case BC_RESULT_VAR: 2613 case BC_RESULT_VAR:
2629 case BC_RESULT_ARRAY: 2614 case BC_RESULT_ARRAY:
2630 case BC_RESULT_ARRAY_ELEM: 2615 case BC_RESULT_ARRAY_ELEM:
2631 {
2632 d->d.id.name = xstrdup(src->d.id.name); 2616 d->d.id.name = xstrdup(src->d.id.name);
2633 break; 2617 break;
2634 }
2635
2636 case BC_RESULT_CONSTANT: 2618 case BC_RESULT_CONSTANT:
2637 case BC_RESULT_LAST: 2619 case BC_RESULT_LAST:
2638 case BC_RESULT_ONE: 2620 case BC_RESULT_ONE:
2639 case BC_RESULT_STR: 2621 case BC_RESULT_STR:
2640 {
2641 memcpy(&d->d.n, &src->d.n, sizeof(BcNum)); 2622 memcpy(&d->d.n, &src->d.n, sizeof(BcNum));
2642 break; 2623 break;
2643 }
2644 } 2624 }
2645} 2625}
2646#endif // ENABLE_DC 2626#endif // ENABLE_DC
@@ -2650,29 +2630,20 @@ static FAST_FUNC void bc_result_free(void *result)
2650 BcResult *r = (BcResult *) result; 2630 BcResult *r = (BcResult *) result;
2651 2631
2652 switch (r->t) { 2632 switch (r->t) {
2653
2654 case BC_RESULT_TEMP: 2633 case BC_RESULT_TEMP:
2655 case BC_RESULT_IBASE: 2634 case BC_RESULT_IBASE:
2656 case BC_RESULT_SCALE: 2635 case BC_RESULT_SCALE:
2657 case BC_RESULT_OBASE: 2636 case BC_RESULT_OBASE:
2658 {
2659 bc_num_free(&r->d.n); 2637 bc_num_free(&r->d.n);
2660 break; 2638 break;
2661 }
2662
2663 case BC_RESULT_VAR: 2639 case BC_RESULT_VAR:
2664 case BC_RESULT_ARRAY: 2640 case BC_RESULT_ARRAY:
2665 case BC_RESULT_ARRAY_ELEM: 2641 case BC_RESULT_ARRAY_ELEM:
2666 {
2667 free(r->d.id.name); 2642 free(r->d.id.name);
2668 break; 2643 break;
2669 }
2670
2671 default: 2644 default:
2672 {
2673 // Do nothing. 2645 // Do nothing.
2674 break; 2646 break;
2675 }
2676 } 2647 }
2677} 2648}
2678 2649