0

Somehow PHP thinks that 3.57 + 0.01 equals 3.5799999999999996 in my script.

I tested about 10 other sums like this (e.g. 10.51 + 0.01) and then PHP gave me the correct answer (10.52 in the latter case). So, weirdly enough it only seems to make this mistake with these specific floats.

Code: (simplified for readability)

$users = array();

$IDs = [1,2,3];

foreach($IDs as $ID)
{
  $user = (object) array();
  $user->ID = $ID;
  $users[] = $user;
}

$initialAmount = 3.57;

$chosenIDs = [1,3];

foreach ($users as $key => $value)
{
  $users[$key]->amount = $initialAmount;
  if(in_array($key, $chosenIDs))
  {
    //the following returns 3.5799999999999996
    $users[$key]->amount = $users[$key]->amount + 0.01;

    //even if I do it like the following, it returns the wrong answer
    $users[$key]->amount = 3.57 + 0.01; //according to PHP equals 3.5799999999999996

    //the following actually gives the correct answer though
    //$users[$key]->amount = ($users[$key]->amount * 100 + 1) / 100;
  }
}

Is this some weird error in my configuration, or what is going on here?

Tafel
  • 1,017
  • 10
  • 17
  • 6
    double and float variable types have limited precisions – Philipp Sander Jul 05 '18 at 13:43
  • 1
    This is not a mistake, but a correct answer. It is inherent in using floats, they have limited precision. See: http://php.net/manual/en/language.types.float.php – KIKO Software Jul 05 '18 at 13:44
  • Ah okay, but 3.57 + 0.01 isn't really that precise and above all not such a difficult sum to be honest ;) . Is it really normal that PHP can't solve that correctly? The weird thing is that it only happens inside this function. Is it possibly related with some sort of shortage of variable storage? Or am I suggesting something completely stupid now? – Tafel Jul 05 '18 at 13:49
  • Ahh I have read the linked document better now, and I understand it better now as well. So my previous comment was indeed stupid, haha. Thanks – Tafel Jul 05 '18 at 13:53

1 Answers1

0

As others have mentioned, it's a problem with Floating Point Math, not php.

http://php.net/manual/en/language.types.float.php

You can avoid it by using the BC Math extension when working with numbers where Floating Point errors would be a problem. It supports arbitrary precision.

http://php.net/manual/en/ref.bc.php

Terry Carmen
  • 3,720
  • 1
  • 16
  • 32