1

Am having an issue where PHP expands the float value e.g. 241.09 becomes 241.0899999999. The issue is, the expanded value is included in a signature, thus the expansion is causing my signature to have a mismatch when matching with the actual data which has the original unexpanded form. How do I prevent the rounding off? My code section is as below:

round(floatval($resultParams["AvailableFunds"]), 2)

Somehow, even after applying the round function, the expansion still occurs. How do I prevent that??

Peter
  • 648
  • 7
  • 26
  • Check this out: https://stackoverflow.com/questions/3726721/php-floating-number-precisio – Brett Gregson Oct 31 '19 at 09:09
  • @BrettGregson the accepted answer from the link says to use round(), but even round doesn't seem to work here. I can actually see the using an integer option answer. Lemme check if I can use that – Peter Oct 31 '19 at 09:11
  • As user2342558 already answered, this is what floating point numbers are like. Don't try to fight it, just accept that they're not an exact representation of the abstract number. Do not use `==` on them, instead test whether they are close enough. – KIKO Software Oct 31 '19 at 09:18
  • Do a search on `IEEE 754 floating point arithmetic rounding error` an bathe in the complexity of floating point numbers – RiggsFolly Oct 31 '19 at 09:18
  • @KIKOSoftware issue is when I have to use them in a signature in PHP. The inexact matching causes the signature to always fail – Peter Oct 31 '19 at 09:19
  • @KIKOSoftware I fought much about this "issue"... If I remember correctly, my answer solved my problem at all. – user2342558 Oct 31 '19 at 09:19
  • This has all the gory details... https://stackoverflow.com/questions/588004/is-floating-point-math-broken – Nick Oct 31 '19 at 09:21

1 Answers1

0

It's caused by the PHP Floating point precision:

Floating point numbers have limited precision.

A solution may be to use only integer, e.g. save the float 123.45 as 12345 and when you need to use display it divide it by 100 and pass it to the number_format function:

$myNumView = number_format($myNum/100, 2, '.', '')+0;

By doing this, number_format returns a string formatted as 1234567.89, then by doing +0 PHP converts it to float (due to the PHP Type Juggling) and removes the rightmost 0 in the decimal part of the number:

$a = '35';
$b = '-34.99';
echo $myNum = ($a + $b);
echo '<br>';
echo $myNumView = number_format($myNum, 4, '.', '')+0;

returns:

0.009999999999998
0.01

And also, why does you get AvailableFunds from a string with floatval? It seems that AvailableFunds is a string containing the amount of fund and other text. I think this is a bad implementation on how saving the fund amount. It's better to save the value as is in a dedicated field as float.

user2342558
  • 5,567
  • 5
  • 33
  • 54