37

I have a method that returns a float like 1.234567890.I want to test that it really does so. However, it seems that this returned float has different precision on different platforms so how do I assert that the returned value is 1.23456789? If I just do:

$this->assertEqual(1.23456789, $float);

Then that might fail on some platforms where there is not enough precision.

Gordon
  • 312,688
  • 75
  • 539
  • 559
Tower
  • 98,741
  • 129
  • 357
  • 507

5 Answers5

85

So far it hasn't been mentioned that assertEquals supports comparing floats by offering a delta to specifiy precision:

$this->assertEquals(1.23456789, $float, '', 0.0001);

Thanks to @Antoine87 for pointing out: since phpunit 7.5 you should use assertEqualsWithDelta():

$this->assertEqualsWithDelta(1.23456789, $float, 0.0001);
Bernhard Wagner
  • 1,681
  • 12
  • 15
  • 4
    Love the simple solutions. This should be the accepted one. Accepted solution would have me digging through BCMath for an hour. – Charlie Dalsass Feb 03 '17 at 19:23
10

As an update to @bernhard-wagner answer, you should now use assertEqualsWithDelta() since phpunit 7.5.

$this->assertEqualsWithDelta(1.23456789, $float, 0.0001);
Bernhard Wagner
  • 1,681
  • 12
  • 15
Antoine87
  • 101
  • 1
  • 2
4

In general, it's a bad idea to test built-in floats for equality. Because of accuracy problems of floating point representation, the results of two different calculations may be perfectly equal mathematically, but different when you compare them at your PHP runtime.

Solution 1: compare how far apart they are. Say, if the absolute difference is less than 0.000001, you treat the values as equal.

Solution 2: use arbitrary precision mathematics, which supports numbers of any size and precision, represented as strings.

Ivan Krechetov
  • 18,802
  • 8
  • 49
  • 60
  • 1
    +1 for never testing floats for equality. Scary how many people are not aware of this. Wish I could upvote more... – sleske Dec 28 '09 at 16:47
  • Right, sleske. I learned it for real long time ago writing my own ray tracing program, and wondering why I only get several dots on the screen instead of beautifully lit polygons. :-) – Ivan Krechetov Dec 28 '09 at 18:13
3

For greater accuracy you may consider using BCMath.

Sarfraz
  • 377,238
  • 77
  • 533
  • 578
0

Alternatively of using bcmath() you can also set the default precision, like this:

ini_set('precision', 14);
Alix Axel
  • 151,645
  • 95
  • 393
  • 500