0

Why does $x1 not equal $z2? I've tried round() as well as explicitly changing the precision to 8. $x1 should equal $z2

$x1 = 251.47267993;
$y1 = 3861.62758730;
$z1 = $x1 / $y1;

echo "{$x1} / {$y1} = {$z1}\n\n"; // ok looks good

$x2 = .06512090;
$y2 = 3861.62758730;
$z2 = $x2 * $y2;

echo "{$x2} x {$y2}  = {$z2}\n\n"; // hmm no - $z2 should be === to $x1

// why do these numbers NOT match? and how can I make them match?
// set some precision somewhere?
echo $x1 . " = " . $z2 . "\n";

More info:

_251.47267993_  /3861.62758730  =.06512090
.06512090     *3861.62758730  =_251.47266394_
251.47267993 - 251.47266394  = .00001599

Note that the 2 underlined numbers should be identical we divided then multiplied by the same number. Should be inverses ... right ... but not when we don't have an infinite number of digits to play with - as is, they are not even close, they differ by "0.00001599"

kero
  • 10,647
  • 5
  • 41
  • 51
Kladskull
  • 10,332
  • 20
  • 69
  • 111
  • possible duplicate of [Compare floats in php](http://stackoverflow.com/q/3148937/1503018) – sectus Mar 06 '14 at 00:37
  • 1
    Unfortunately not a duplicate – Kladskull Mar 06 '14 at 00:39
  • They are not equal because that's how floating point arithmetic works. So - duplicate – zerkms Mar 06 '14 at 00:42
  • The leading 7 digits (251.4726) coincide in both numbers, you can not expect more from the 32bit float type. – Lutz Lehmann Mar 06 '14 at 15:51
  • @LutzL: These are almost certainly double-precision floats, not single-precision. The main source of error is from reusing the truncated output string for `z1` as the numeric literal for defining `x2`. – Mark Dickinson Mar 06 '14 at 17:12
  • OK, I stand corrected. And yes, now that you say it, there are only 7 significant digits in x2, which causes the result also to have only at most 7 valid or significant digits. – Lutz Lehmann Mar 06 '14 at 17:17

3 Answers3

1

Don't know what your purpose is, but why are you not doing this?

$x = 251.47267993;
$y = 3861.62758730;

$z1 = $x / $y;

$z2 = $z1 * $y;

echo $x . " = " . $z2 . "\n";

Equals everytime

ElefantPhace
  • 3,806
  • 3
  • 20
  • 36
1

There is another problem: echoing float value. You have to increase your precision.

echo 1 / 3, PHP_EOL;      // 0.33333333333333
ini_set('precision', 60);
echo 1 / 3, PHP_EOL;      // 0.333333333333333314829616256247390992939472198486328125

Why are you trying to use value from screen but not from variable?

sectus
  • 15,605
  • 5
  • 55
  • 97
0

In PHP built-in functions are not exactly the best for that kind of calculations. For example:

echo (int) ((0.1 + 0.7) * 10);

will output 7 instead of 8.

Anyways, 251.47267993 / 3861.62758730 is not 0.06512090. Depending on the computer architecture when doing this computing it will print different results. For me it printed 0.065120904138202, which is perfectly fine because the precision is about ~14 decimal digits in a floating point.

What you can do, is use BCMath library, which is documented really good in the php.net manual. For this particular situation, you could use:

$z1 = bcdiv($x1, $y1, 200);

instead of:

$z1 = $x1 / $y1;

And see that this number is not that small what you've been thinking. For more information, check this out BCMath library.

sunshinejr
  • 4,834
  • 2
  • 22
  • 32