3

this operation

$data['can_redeem'] = $data['payments_client']['accumulated']>=floatval($data['charge_limit'])

where $data['payments_client']['accumulated'] = 7.0 and $data['charge_limit'] = "7" is giving false. It has to be something about the types but in appearance both variables have the same value.

brombeer
  • 8,716
  • 5
  • 21
  • 27
afdi5
  • 307
  • 2
  • 13
  • try converting both to int forst – treyBake Apr 05 '19 at 08:10
  • 4
    Your assumption is that this should evaluate to something like 7.0 = 7. This is not a type issue, but a floating point issue. 7.0 is probably not exactly 7.0, but more something like 7.0000000000000000001 or 6.99999999999999999999 hence your comparison operator doesn't work as expected. See: https://www.php.net/manual/en/language.types.float.php (read the big red box) – KIKO Software Apr 05 '19 at 08:11
  • 2
    Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Andrei Lupuleasa Apr 05 '19 at 08:14
  • Are you 100% sure those are the values in your variables? [This test](https://3v4l.org/sKDQP) doesn't give me the same results as you describe. – M. Eriksson Apr 05 '19 at 08:15
  • 3
    Ran a test now and ```7.0 >= floatval("7")``` returns `true`. You are advised to check the value of `$data['payments_client']['accumulated']` and confirm if it is actually holding a possible comparison value. `print_r($data['payments_client']['accumulated']); ` – Erisan Olasheni Apr 05 '19 at 08:15
  • @ErisanOlasheni You cannot rely on a floating point value to be an exact value. It is always an approximation, probably a very accurate one, but still only an approximation. – KIKO Software Apr 05 '19 at 08:17
  • @KIKOSoftware Yes what I mean it to confirm if the variable is actually holding a possible comparison value, this is a variable we don't know the source and might have been holding anything! – Erisan Olasheni Apr 05 '19 at 08:19
  • @ErisanOlasheni Advicing afdi5 to check the value is actually '7.0' is the wrong advice. He should rewrite the comparison. Something like `abs(A - B) < 0.0000001` (this is just an example, the real solution depends on what the numbers represent and which comparison needs to be made). – KIKO Software Apr 05 '19 at 08:21
  • @KIKOSoftware This is still not clear and not easy to understand, use an example to matches his use case. – Erisan Olasheni Apr 05 '19 at 08:26
  • @ErisanOlasheni OK, what about: `$data['payments_client']['accumulated'] >= $data['charge_limit']-1E-10`? – KIKO Software Apr 05 '19 at 08:28
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/191302/discussion-between-erisan-olasheni-and-kiko-software). – Erisan Olasheni Apr 05 '19 at 08:29

1 Answers1

1

The code

$data['payments_client']['accumulated'] = 7.0;
$data['charge_limit'] = "7" ;
$data['can_redeem'] = $data['payments_client']['accumulated'] >= floatval($data['charge_limit']);
echo ($data['can_redeem']? 'True': 'False');

emulates your example, you will get the result as 'True' in this case as advised in the comments.

However, as a general rule it is safer to use:

$data['can_redeem'] = abs($data['payments_client']['accumulated']-floatval($data['charge_limit'])) < 0.0001;

as your conditional so that there is no risk of floating point issues. Note, you can change the '0.0001' to '0.01' or '0.000001' depending on your needs.

If you still get 'False' then you need to debug your code to check the values in $data['payments_client']['accumulated'] and in $data['charge_limit'].

Clinton
  • 1,111
  • 1
  • 14
  • 21