diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-22 21:37:46 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-22 21:37:46 +0100 |
commit | 1557b76edde8bc810f82ac67e3b83b2d6ccce51c (patch) | |
tree | 68cb23b301a45439f993f98c2105861dfc385673 /miscutils | |
parent | ec74a9c14572f17ad4a5ff94813a743bc6e6222d (diff) | |
download | busybox-w32-1557b76edde8bc810f82ac67e3b83b2d6ccce51c.tar.gz busybox-w32-1557b76edde8bc810f82ac67e3b83b2d6ccce51c.tar.bz2 busybox-w32-1557b76edde8bc810f82ac67e3b83b2d6ccce51c.zip |
bc: shrink zbc_num_ulong()
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/bc.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 7be2d0b9b..876244b34 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -1442,20 +1442,21 @@ static void bc_num_copy(BcNum *d, BcNum *s) | |||
1442 | static BC_STATUS zbc_num_ulong(BcNum *n, unsigned long *result_p) | 1442 | static BC_STATUS zbc_num_ulong(BcNum *n, unsigned long *result_p) |
1443 | { | 1443 | { |
1444 | size_t i; | 1444 | size_t i; |
1445 | unsigned long pow, result; | 1445 | unsigned long result; |
1446 | 1446 | ||
1447 | if (n->neg) RETURN_STATUS(bc_error("negative number")); | 1447 | if (n->neg) RETURN_STATUS(bc_error("negative number")); |
1448 | 1448 | ||
1449 | for (result = 0, pow = 1, i = n->rdx; i < n->len; ++i) { | 1449 | result = 0; |
1450 | unsigned long prev = result, powprev = pow; | 1450 | i = n->len; |
1451 | 1451 | while (i > n->rdx) { | |
1452 | result += ((unsigned long) n->num[i]) * pow; | 1452 | unsigned long prev = result; |
1453 | pow *= 10; | 1453 | result = result * 10 + n->num[--i]; |
1454 | 1454 | // Even overflowed N*10 can still satisfy N*10>=N. For example, | |
1455 | if (result < prev || pow < powprev) | 1455 | // 0x1ff00000 * 10 is 0x13f600000, |
1456 | // or 0x3f600000 truncated to 32 bits. Which is larger. | ||
1457 | // However, (N*10)/8 < N check is always correct. | ||
1458 | if ((result / 8) < prev) | ||
1456 | RETURN_STATUS(bc_error("overflow")); | 1459 | RETURN_STATUS(bc_error("overflow")); |
1457 | prev = result; | ||
1458 | powprev = pow; | ||
1459 | } | 1460 | } |
1460 | *result_p = result; | 1461 | *result_p = result; |
1461 | 1462 | ||