文字

bcmul

(PHP 4, PHP 5, PHP 7)

bcmul2个任意精度数字乘法计算

说明

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

左操作数乘以右操作数

参数

left_operand

字符串类型的左操作数.

right_operand

字符串类型的右操作数.

scale

此可选参数用于设置结果中小数点后的小数位数。也可通过使用 bcscale() 来设置全局默认的小数位数,用于所有函数。

返回值

返回结果为字符串类型.

范例

Example #1 bcmul() 示例

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

参见

  • bcdiv() - 2个任意精度的数字除法计算

用户评论:

[#1] gar37bic at gmail dot com [2012-11-19 17:06:20]

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) = 1124000727777607680000
factorial (23) = 25852016738884976640000

Using echo, this is not a problem - PHP will output the bcmath string type correctly.

[#2] admin at spamhere dot sinfocol dot org [2011-01-03 22:17:01]

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.

<?php
echo 'Left Shift test<br />';
bprint('1'decbin(1));
bprint('1 << 32 (Fail)'decbin(<< 32)); //Fail, operation not succesfull in 32-bit machine
bprint('shiftleft(1, 32) (Success)'dec2bin(shiftleft('1''32'))); //decbin fails, so we use personalized function, success

echo '<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($numbcpow('2'$bits));
}

function 
rightshift($num$bits) {
    return 
bcdiv($numbcpow('2'$bits));
}

function 
bprint($title$content) {
    echo 
$title '<br />' str_pad($content64'0'STR_PAD_LEFT) . '<br />' PHP_EOL;
}

//http://www.php.net/manual/en/function.decbin.php#99533
function 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;
}
?>

[#3] Nitrogen [2009-07-08 17:55:37]

I made this to multiply an unlimited size of integers together (meaning no decimals)..
This could be useful for those without the BCMath extension.

<?php

function 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



?>


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.

[#4] ju(...) [2008-04-02 00:00:54]

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).

上一篇: 下一篇: