PHP Unconference Europe 2015

bcadd

(PHP 4, PHP 5)

bcaddAdditionne deux nombres de grande taille

Description

string bcadd ( string $left_operand , string $right_operand [, int $scale ] )

Additionne left_operand et right_operand.

Liste de paramètres

left_operand

L'opérande gauche, sous la forme d'une chaîne de caractères.

right_operand

L'opérande droite, sous la forme d'une chaîne de caractères.

scale

Ce paramètre optionnel est utilisé pour définir le nombre de digits après la décimale à placer dans le résultat. Vous pouvez également définir la précision globale par défaut pour toutes les fonctions en utilisant la fonction bcscale().

Valeurs de retour

La somme des deux opérandes, sous la forme d'une chaîne de caractères.

Exemples

Exemple #1 Exemple avec bcadd()

<?php
$a 
'1.234';
$b '5';

echo 
bcadd($a$b);     // 6
echo bcadd($a$b4);  // 6.2340
?>

Voir aussi

  • bcsub() - Soustrait un nombre de grande taille d'un autre

add a note add a note

User Contributed Notes 2 notes

up
8
Nitrogen
5 years ago
I made this to add an unlimited size of numbers together..

This could be useful for those without the BCMath extension.

It allows decimals, and optional $Scale parameter.  If $Scale isn't specified, then it'll automatically adjust to show the correct number of decimals.

<?php

function Add($Num1,$Num2,$Scale=null) {
 
// check if they're valid positive numbers, extract the whole numbers and decimals
 
if(!preg_match("/^\+?(\d+)(\.\d+)?$/",$Num1,$Tmp1)||
     !
preg_match("/^\+?(\d+)(\.\d+)?$/",$Num2,$Tmp2)) return('0');

 
// this is where the result is stored
 
$Output=array();

 
// remove ending zeroes from decimals and remove point
 
$Dec1=isset($Tmp1[2])?rtrim(substr($Tmp1[2],1),'0'):'';
 
$Dec2=isset($Tmp2[2])?rtrim(substr($Tmp2[2],1),'0'):'';

 
// calculate the longest length of decimals
 
$DLen=max(strlen($Dec1),strlen($Dec2));

 
// if $Scale is null, automatically set it to the amount of decimal places for accuracy
 
if($Scale==null) $Scale=$DLen;

 
// remove leading zeroes and reverse the whole numbers, then append padded decimals on the end
 
$Num1=strrev(ltrim($Tmp1[1],'0').str_pad($Dec1,$DLen,'0'));
 
$Num2=strrev(ltrim($Tmp2[1],'0').str_pad($Dec2,$DLen,'0'));

 
// calculate the longest length we need to process
 
$MLen=max(strlen($Num1),strlen($Num2));

 
// pad the two numbers so they are of equal length (both equal to $MLen)
 
$Num1=str_pad($Num1,$MLen,'0');
 
$Num2=str_pad($Num2,$MLen,'0');

 
// process each digit, keep the ones, carry the tens (remainders)
 
for($i=0;$i<$MLen;$i++) {
   
$Sum=((int)$Num1{$i}+(int)$Num2{$i});
    if(isset(
$Output[$i])) $Sum+=$Output[$i];
   
$Output[$i]=$Sum%10;
    if(
$Sum>9) $Output[$i+1]=1;
  }

 
// convert the array to string and reverse it
 
$Output=strrev(implode($Output));

 
// substring the decimal digits from the result, pad if necessary (if $Scale > amount of actual decimals)
  // next, since actual zero values can cause a problem with the substring values, if so, just simply give '0'
  // next, append the decimal value, if $Scale is defined, and return result
 
$Decimal=str_pad(substr($Output,-$DLen,$Scale),$Scale,'0');
 
$Output=(($MLen-$DLen<1)?'0':substr($Output,0,-$DLen));
 
$Output.=(($Scale>0)?".{$Decimal}":'');
  return(
$Output);
}

$A="5650175242.508133742";
$B="308437806.831153821478770";

printf("  Add(%s,%s);\r\n// %s\r\n\r\n",$A,$BAdd($A,$B));
printf("BCAdd(%s,%s);\r\n// %s\r\n\r\n",$A,$B,BCAdd($A,$B));

/*
  This will produce the following..
    Add(5650175242.508133742,308437806.831153821478770);
  // 5958613049.33928756347877

  BCAdd(5650175242.508133742,308437806.831153821478770);
  // 5958613049
*/

?>

It was a fun experience making, and thought I'd share it.
Enjoy,
Nitrogen.
up
2
Bo Anders Svensson
9 years ago
Be aware:

$exp1 = "1E5";
$exp2 = "2E4";

$ans1 = bcadd((float)$exp1, (float)$exp2, 3);
$ans2 = bcadd((int)$exp1, (int)$exp2, 3);
$ans3 = bcadd($exp1, $exp2, 3);

echo "1: $exp1 + $exp2 = $ans1\r\n";
echo "2: $exp1 + $exp2 = $ans2\r\n";
echo "3: $exp1 + $exp2 = $ans3\r\n";

1: 1E5 + 2E4 = 120000.000
2: 1E5 + 2E4 = 3.000
3: 1E5 + 2E4 = 0.000
To Top