Patch bcmul-scale for BC math related Bug #66364
Patch version 2013-12-28 03:40 UTC
Return to Bug #66364 |
Download this patch
Patch Revisions:
Developer: self@jacobbudin.com
From db21e4bc52ee248d7b58d18116cfa44ea6dd656e Mon Sep 17 00:00:00 2001
From: Jacob Budin <self@jacobbudin.com>
Date: Fri, 27 Dec 2013 22:32:26 -0500
Subject: [PATCH] bcmul scale parameter fix for trailing zeros
---
ext/bcmath/libbcmath/src/recmul.c | 37 +++++++++++++++++++++++++------------
ext/bcmath/tests/bcmul.phpt | 2 ++
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c
index 64014f3..400da86 100644
--- a/ext/bcmath/libbcmath/src/recmul.c
+++ b/ext/bcmath/libbcmath/src/recmul.c
@@ -277,27 +277,40 @@ _bc_rec_mul (bc_num u, int ulen, bc_num v, int vlen, bc_num *prod,
void
bc_multiply (bc_num n1, bc_num n2, bc_num *prod, int scale TSRMLS_DC)
{
- bc_num pval;
+ bc_num pval, pval_scaled;
int len1, len2;
- int full_scale, prod_scale;
+ int full_scale, full_length;
+ char *scaled_ptr, *original_ptr;
+ int count, cutoff;
/* Initialize things. */
len1 = n1->n_len + n1->n_scale;
len2 = n2->n_len + n2->n_scale;
full_scale = n1->n_scale + n2->n_scale;
- prod_scale = MIN(full_scale,MAX(scale,MAX(n1->n_scale,n2->n_scale)));
+ full_length = len1 + len2 + 1 - full_scale;
/* Do the multiply */
_bc_rec_mul (n1, len1, n2, len2, &pval, full_scale TSRMLS_CC);
- /* Assign to prod and clean up the number. */
- pval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );
- pval->n_value = pval->n_ptr;
- pval->n_len = len2 + len1 + 1 - full_scale;
- pval->n_scale = prod_scale;
- _bc_rm_leading_zeros (pval);
- if (bc_is_zero (pval TSRMLS_CC))
- pval->n_sign = PLUS;
+ /* Assign to prod and clean up the number, appending zeros if necessary */
+ pval_scaled = bc_new_num(full_length, scale);
+ pval_scaled->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );
+
+ scaled_ptr = (char *) pval_scaled->n_value;
+ original_ptr = (char *) pval->n_value;
+ cutoff = pval_scaled->n_len + pval_scaled->n_scale - pval->n_len - pval->n_scale;
+
+ for(count = pval_scaled->n_len + pval_scaled->n_scale; count > 0; count--){
+ if(count > cutoff){
+ *scaled_ptr++ = *original_ptr++;
+ }
+ else{
+ *scaled_ptr++ = 0;
+ }
+ }
+ _bc_rm_leading_zeros (pval_scaled);
+ if (bc_is_zero (pval_scaled TSRMLS_CC))
+ pval_scaled->n_sign = PLUS;
bc_free_num (prod);
- *prod = pval;
+ *prod = pval_scaled;
}
diff --git a/ext/bcmath/tests/bcmul.phpt b/ext/bcmath/tests/bcmul.phpt
index 0ff322f..1c041c0 100644
--- a/ext/bcmath/tests/bcmul.phpt
+++ b/ext/bcmath/tests/bcmul.phpt
@@ -10,9 +10,11 @@ echo bcmul("1", "2"),"\n";
echo bcmul("-3", "5"),"\n";
echo bcmul("1234567890", "9876543210"),"\n";
echo bcmul("2.5", "1.5", 2),"\n";
+echo bcmul("0.3", "0.2", 4),"\n";
?>
--EXPECT--
2
-15
12193263111263526900
3.75
+0.0600
--
1.8.4.2
|