php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #66364
Patch bcmul-scale revision 2013-12-28 03:40 UTC by self at jacobbudin dot com

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

 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Thu Aug 18 23:03:49 2022 UTC