0

PHP

<?php echo (-9.341+2.111);

Result -7.23

Javascript

console.log(2.111-9.341)

Result -7.229999999999999

I'm aware of floating Arithmetic, but why vanilla PHP give exact answer and Javascript (tested on Google Chrome console) not?

Fabiano Taioli
  • 5,270
  • 1
  • 35
  • 49
  • You'll find plenty of spots where PHP gives you the repeating numbers too. – ceejayoz Jul 13 '17 at 22:08
  • http://stackoverflow.com/questions/588004/is-floating-point-math-broken –  Jul 13 '17 at 22:09
  • Both [JavaScript](https://www.ecma-international.org/ecma-262/5.1/#sec-4.3.19) and [PHP](http://php.net/manual/en/language.types.float.php) use IEEE 754, echo is probably rounding (note whether a PHP floating point is 32b or 64b is platform dependent) – Patrick Barr Jul 13 '17 at 22:09
  • `-7.23` appears to have no finite binary representation. – ASDFGerte Jul 13 '17 at 22:10
  • `echo (-9.341+2.111 == -7.23 ? "true" : "false");` result: false – James Jul 13 '17 at 22:12
  • @James given that `-7.23` cannot be represented exactly, your example proves nothing. – zerkms Jul 13 '17 at 22:12
  • It proves that echo is rounding? – James Jul 13 '17 at 22:12
  • @James I fail to see how it does: you compare one imprecise value with another imprecise value. – zerkms Jul 13 '17 at 22:13
  • @zerkms we're not trying to prove that -7.23 does or does not have a precise representation in base 2, rather that php doesn't improve over javascript in doing "exact" base-10 math, and that something is affecting the result when it's echoed. – James Jul 13 '17 at 22:20
  • @James there easily might be a number that does not have exact representation and that is equal to the literal. In that case your example would return true. The result basically depends on how both values were evaluated (and how large the error is) and on nothing more. – zerkms Jul 13 '17 at 22:21
  • @James `0.1 + 0.1 === 0.2 // true`, even though none of them have exact IEEE754 representation. – zerkms Jul 13 '17 at 22:24
  • @zerkms My example doesn't have to return false for all values, just 1 case is sufficient to disprove the OP's theory. – James Jul 13 '17 at 22:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149179/discussion-between-zerkms-and-james). – zerkms Jul 13 '17 at 22:24

1 Answers1

1

It is php's echo that is rounding:

var_dump(sprintf('%.20f', -9.341+2.111)); // string(23) "-7.22999999999999864997"

In php sources it looks that echo would convert a floating point number to a string using the following conversion:

str = zend_strpprintf(0, "%.*G", (int) EG(precision), dval);

Which basically means either scientific notation or %f (see precision configuration directive, 14 by default).

zerkms
  • 249,484
  • 69
  • 436
  • 539