diff options
author | Denys Vlasenko | 2021-02-26 14:05:28 +0100 |
---|---|---|
committer | Denys Vlasenko | 2021-02-26 14:23:13 +0100 |
commit | ace81cd46ce53e60fe702cc1ac857989207e7ac4 (patch) | |
tree | f9d8bd67c672ad9c586dd85e03f976bd2206fe71 | |
parent | 3d88cc1d371a4a5ae8e1521a1e915479bca52959 (diff) | |
download | busybox-ace81cd46ce53e60fe702cc1ac857989207e7ac4.zip busybox-ace81cd46ce53e60fe702cc1ac857989207e7ac4.tar.gz |
bc/dc: fix length(0) and length(0.000nnn) result
function old new delta
zxc_vm_process 6464 6498 +34
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 17 | ||||
-rwxr-xr-x | testsuite/bc.tests | 5 | ||||
-rwxr-xr-x | testsuite/dc.tests | 5 |
3 files changed, 23 insertions, 4 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 84bbe7b..9156409 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -6259,13 +6259,20 @@ static unsigned long xc_program_len(BcNum *n) { size_t len = n->len; - if (n->rdx != len) return len; + if (n->rdx != len) + // length(100): rdx 0 len 3, return 3 + // length(0.01-0.01): rdx 2 len 0, return 2 + // dc: 0.01 0.01 - Zp: rdx 2 len 0, return 1 + return len != 0 ? len : (IS_BC ? n->rdx : 1); + + // length(0): return 1 + // length(0.000nnn): count nnn for (;;) { if (len == 0) break; len--; if (n->num[len] != 0) break; } - return len; + return len + 1; } static BC_STATUS zxc_program_builtin(char inst) @@ -6293,12 +6300,12 @@ static BC_STATUS zxc_program_builtin(char inst) if (inst == XC_INST_SQRT) s = zbc_num_sqrt(num, &res.d.n, G.prog.scale); #if ENABLE_BC - else if (len != 0 && opnd->t == XC_RESULT_ARRAY) { + else if (len && opnd->t == XC_RESULT_ARRAY) { bc_num_ulong2num(&res.d.n, (unsigned long) ((BcVec *) num)->len); } #endif #if ENABLE_DC - else if (len != 0 && !BC_PROG_NUM(opnd, num)) { + else if (len && !BC_PROG_NUM(opnd, num)) { char **str; size_t idx = opnd->t == XC_RESULT_STR ? opnd->d.id.idx : num->rdx; @@ -6307,6 +6314,8 @@ static BC_STATUS zxc_program_builtin(char inst) } #endif else { +//TODO: length(.00) and scale(.00) should return 2, they return 1 and 0 now +//(don't forget to check that dc Z and X commands do not break) bc_num_ulong2num(&res.d.n, len ? xc_program_len(num) : xc_program_scale(num)); } diff --git a/testsuite/bc.tests b/testsuite/bc.tests index 179d5d2..1c74872 100755 --- a/testsuite/bc.tests +++ b/testsuite/bc.tests @@ -182,6 +182,11 @@ testing "bc print 1,2,3" \ "123" \ "" "print 1,2,3" +testing "bc length" \ + "bc" \ + "1\n3\n1\n3\n3\n" \ + "" "length(0); length(100); length(0.01); length(0.00120); length(0.012-0.012);" + testing "bc { print 1 }" \ "bc" \ "1" \ diff --git a/testsuite/dc.tests b/testsuite/dc.tests index 361bc84..ad00993 100755 --- a/testsuite/dc.tests +++ b/testsuite/dc.tests @@ -114,6 +114,11 @@ testing "dc newline can be a register" \ "2\n9\n" \ "" "[2p]s\n[3p]l\nx\n9p" +testing "dc Z (length) for numbers" \ + "dc" \ + "1\n1\n3\n1\n3\n1\n" \ + "" "0Zp\n0.000Zp\n100Zp\n0.01Zp\n0.00120Zp\n0.0012 0.0012 - Zp\n" + for f in dc_*.dc; do r="`basename "$f" .dc`_results.txt" test -f "$r" || continue |