bcmul

(PHP 4, PHP 5, PHP 7, PHP 8)

bcmulMultiplica dois números de precisão arbitrária

Descrição

bcmul(string $num1, string $num2, ?int $scale = null): string

Multiplica num1 por num2.

Parâmetros

num1

O operando da esquerda, como uma string.

num2

O operando da direita, como uma string.

scale
Este parâmetro é usado para definir o número de dígitos após o separador de decimais do resultado. Se for null, será usada a escala padrão definida com bcscale(), ou será usado o valor da diretiva INI bcmath.scale.

Valor Retornado

Retorna o resultado como uma string.

Erros/Exceções

Esta função lança uma exceção ValueError nos seguintes casos:

  • num1 ou num2 não for uma string numérica BCMath bem formada.
  • scale estiver fora do intervalo válido.

Registro de Alterações

Versão Descrição
8.0.0 scale agora pode ser nulo.
7.3.0 bcmul() agora retorna números com a escala solicitada. Formalmente o número retornado pode ter alguns zeros decimais omitidos.

Exemplos

Exemplo #1 Exemplo de bcmul()

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

Notas

Nota:

Anteriormente ao PHP 7.3.0, bcmul() poderia retornar um número com menos dígitos após o ponto decimal em comparação ao que o parâmetro scale indicaria. Isto ocorre apenas quando o resultado não exige toda a precisão permitida pelo parâmetro scale. Por exemplo:

Exemplo #2 Exemplo de bcmul() com escala

<?php
echo bcmul('5', '2', 2); // Exibe "10", não "10.00"
?>

Veja Também

adicione uma nota

Notas Enviadas por Usuários (em inglês) 4 notes

up
10
Nitrogen
16 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.
up
7
mgkirs
7 years ago
$float = 0.31234144143341;$float1 = 0.00000000000000000000000000000005;echo $float, "\n";//0.31234144143341echo $float1, "\n";//5.0E-32echo $float*$float1, "\n";//1.5617072071671E-32<?php/*bcmul read float as string*/echo bcmul($float, $float1, 32),"\n";//0echo bcmul($float, sprint('%.32f',$float1), 32);//0.000000000000000000000000000000015617072071671;?>
up
4
admin at spamhere dot sinfocol dot org
14 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;}?>
up
0
gar37bic at gmail dot com
12 years 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.
To Top