Miguel Vieira
Miguel Vieira

Reputation: 154

How to multiply small floats with unkown number of decimal places in PHP withouth getting zero because of scientific notation?

I'm trying to multiply some small numbers in PHP, but bcmul is returning zero because the float value is being turned into scientific notation.

I tried using sprintf('%.32f',$value) on the small float values, but since the number of decimal places is unknown, it gets the wrong rounding, and then it'll cause rounding errors when multiplying.

Also, I can't use strpos('e',$value) to find out if it's scientific notation number, because it doesn't finds it even if I cast it as a string with (string)$value

Here's some example code:

  $value = (float)'7.4e-5'; // This number comes from an API like this

  $value2 = (float)3.65; // Another number from API

  echo bcmul($value,$value2); // 0

Upvotes: 1

Views: 334

Answers (2)

Miguel Vieira
Miguel Vieira

Reputation: 154

Okay, I found a way to solve it, so, here's how to multiply very small floating point numbers without needing to set an explicit scale for the numbers:

function getDecimalPlaces($value) {
// first we get how many decimal places the small number has
// this code was gotten on another StackOverflow answer

   $current = $value - floor($value);
   for ($decimals = 0; ceil($current); $decimals++) {
      $current = ($value * pow(10, $decimals + 1)) - floor($value * pow(10, $decimals + 1));
   }
   return $decimals;
} 

function multiplySmallNumbers($value, $smallvalue) {
    
   $decimals = getDecimalPlaces($smallvalue); // Then we get number of decimals on it
   $smallvalue = sprintf('%.'.$decimals.'f',$smallvalue ); // Since bcmul uses the float values as strings, we get the number as a string with the correct number of zeroes
   return (bcmul($value,$smallvalue));
}

Upvotes: 0

PtrTon
PtrTon

Reputation: 3835

By default the bc-functions round to 0 decimals. You can change this behavior by either using bcscale or by by changing the bcmath.scale value in your php.ini.

Upvotes: 1

Related Questions