ConFoo: Call for paper is now Open

# bcmul

(PHP 4, PHP 5)

bcmulMultiply two arbitrary precision numbers

### Description

string bcmul ( string `\$left_operand` = "" , string `\$right_operand` = "" [, int `\$scale` = int ] )

Multiply the `left_operand` by the `right_operand`.

### Parameters

`left_operand`

The left operand, as a string.

`right_operand`

The right operand, as a string.

``` scale```

This optional parameter is used to set the number of digits after the decimal place in the result. You can also set the global default scale for all functions by using bcscale().

### Return Values

Returns the result as a string.

### Examples

Example #1 bcmul() example

``` <?phpecho bcmul('1.34747474747', '35', 3); // 47.161echo bcmul('2', '4'); // 8?> ```

• bcdiv() - Divide two arbitrary precision numbers

### User Contributed Notes 4 notes

Nitrogen
5 years ago
``` I made this to multiply an unlimited size of integers together (meaning no decimals)..This could be useful for those without the BCMath extension.<?phpfunction Mul(\$Num1='0',\$Num2='0') {  // check if they're both plain numbers  if(!preg_match("/^\d+\$/",\$Num1)||!preg_match("/^\d+\$/",\$Num2)) return(0);  // remove zeroes from beginning of numbers  for(\$i=0;\$i<strlen(\$Num1);\$i++) if(@\$Num1{\$i}!='0') {\$Num1=substr(\$Num1,\$i);break;}  for(\$i=0;\$i<strlen(\$Num2);\$i++) if(@\$Num2{\$i}!='0') {\$Num2=substr(\$Num2,\$i);break;}  // get both number lengths  \$Len1=strlen(\$Num1);  \$Len2=strlen(\$Num2);  // \$Rema is for storing the calculated numbers and \$Rema2 is for carrying the remainders  \$Rema=\$Rema2=array();  // we start by making a \$Len1 by \$Len2 table (array)  for(\$y=\$i=0;\$y<\$Len1;\$y++)    for(\$x=0;\$x<\$Len2;\$x++)      // we use the classic lattice method for calculating the multiplication..      // this will multiply each number in \$Num1 with each number in \$Num2 and store it accordingly      @\$Rema[\$i++%\$Len2].=sprintf('%02d',(int)\$Num1{\$y}*(int)\$Num2{\$x});  // cycle through each stored number  for(\$y=0;\$y<\$Len2;\$y++)    for(\$x=0;\$x<\$Len1*2;\$x++)      // add up the numbers in the diagonal fashion the lattice method uses      @\$Rema2[Floor((\$x-1)/2)+1+\$y]+=(int)\$Rema[\$y]{\$x};  // reverse the results around  \$Rema2=array_reverse(\$Rema2);  // cycle through all the results again  for(\$i=0;\$i<count(\$Rema2);\$i++) {    // reverse this item, split, keep the first digit, spread the other digits down the array    \$Rema3=str_split(strrev(\$Rema2[\$i]));    for(\$o=0;\$o<count(\$Rema3);\$o++)      if(\$o==0) @\$Rema2[\$i+\$o]=\$Rema3[\$o];      else @\$Rema2[\$i+\$o]+=\$Rema3[\$o];  }  // implode \$Rema2 so it's a string and reverse it, this is the result!  \$Rema2=strrev(implode(\$Rema2));  // just to make sure, we delete the zeros from the beginning of the result and return  while(strlen(\$Rema2)>1&&\$Rema2{0}=='0') \$Rema2=substr(\$Rema2,1);  return(\$Rema2);}\$A='5650175242508133742';\$B='2361030539975818701734615584174625';printf("  Mul(%s,%s); // %s\r\n",\$A,\$B,  Mul(\$A,\$B));printf("BCMul(%s,%s); // %s\r\n",\$A,\$B,BCMul(\$A,\$B)); // build-in function/*  This will print something similar to this..    Mul(5650175242508133742,2361030539975818701734615584174625);  BCMul(5650175242508133742,2361030539975818701734615584174625);  both of which should be followed by the answer:  13340236303776981390475700774516825287352418182696750*/?>It was a fun experience making.. even though this took me longer than the BCAdd alternative I did..Memory allocation might be an issue for rediculously larger numbers though.. if someone wants to benchmark the performance of my function; feel free.Enjoy,Nitrogen. ```
gar37bic at gmail dot com
1 year ago
``` When using printf to print the results of bcmath operations, use string format, i.e. '%s', not numeric formats such as '%d' or '%f'.  For example, the output of factorial (23) will be incorrect if using %d or %f:Result using %f:factorial (22) = 1124000727777607680000 (correct)factorial (23) = 25852016738884978212864 (incorrect)Result using %s:factorial (22) = 1124000727777607680000factorial (23) = 25852016738884976640000Using echo, this is not a problem - PHP will output the bcmath string type correctly. ```
admin at spamhere dot sinfocol dot org
3 years ago
``` Well, I have a little problem implementing Blake Hash in my server because it is not a x64 server machine. I made a little function that use the powerfull of BC library to do the bitwise operation Shift.<?phpecho 'Left Shift test<br />';bprint('1', decbin(1));bprint('1 << 32 (Fail)', decbin(1 << 32)); //Fail, operation not succesfull in 32-bit machinebprint('shiftleft(1, 32) (Success)', dec2bin(shiftleft('1', '32'))); //decbin fails, so we use personalized function, successecho '<br />';echo 'Right Shift test<br />';bprint('9223372036854775808', dec2bin('9223372036854775808'));bprint('9223372036854775808 >> 63 (Fail)', decbin(9223372036854775808 >> 63));bprint('rightshift(9223372036854775808, 63) (Success)', decbin(rightshift('9223372036854775808', '63')));function shiftleft(\$num, \$bits) {    return bcmul(\$num, bcpow('2', \$bits));}function rightshift(\$num, \$bits) {    return bcdiv(\$num, bcpow('2', \$bits));}function bprint(\$title, \$content) {    echo \$title . '<br />' . str_pad(\$content, 64, '0', STR_PAD_LEFT) . '<br />' . PHP_EOL;}//http://www.php.net/manual/en/function.decbin.php#99533function dec2bin(\$dec) {    // Better function for dec to bin. Support much bigger values, but doesnâ€™t support signs    for (\$b = '', \$r = \$dec; \$r >1;) {        \$n = floor(\$r / 2);        \$b = (\$r - \$n * 2) . \$b;        \$r = \$n; // \$r%2 is inaccurate when using bigger values (like 11.435.168.214)!    }    return (\$r % 2) . \$b;}?> ```
-2
ju(...)
6 years ago
``` Except that with xpheas method, you lose all the benefits of arbitrary precision as the * operator only works on int and float and those are restricted in length (See int ant float types for more information). ```