php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61855 Wrong division of float numbers
Submitted: 2012-04-26 06:53 UTC Modified: 2012-04-26 08:16 UTC
From: martin dot edlman at gmail dot com Assigned:
Status: Not a bug Package: Math related
PHP Version: 5.3.10 OS: Linux
Private report: No CVE-ID: None
 [2012-04-26 06:53 UTC] martin dot edlman at gmail dot com
Description:
------------
---
From manual page: http://www.php.net/function.floor#refsect1-function.floor-description
---
I encountered problem when dividing float numbers. It's simple formula which can be solved by 10 year old child. But not by PHP! See example.
The problem is that displayed value (3) doesn't correspond with internal value 2.999999999999999 and floor() then returns 2 which is obviously incorrect result! And that's serious problem.

The same code in C returns correct numbers.


Test script:
---------------
<?php
$a = 1.2;
$b = 0.4;
$v = $a / $b;
printf("v(15) = %.15f\n", $v);
printf("v(16) = %.16f\n", $v);
print "v = $v\n";
print "floor(v) = ".floor($v)."\n";
?>


Expected result:
----------------
v(15) = 3.000000000000000
v(16) = 3.0000000000000000
v = 3
floor(v) = 3


Actual result:
--------------
v(15) = 3.000000000000000
v(16) = 2.9999999999999996
v = 3
floor(v) = 2


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-04-26 07:33 UTC] pajoye@php.net
Floating point values have a limited precision. Hence a value might 
not have the same string representation after any processing. That also
includes writing a floating point value in your script and directly 
printing it without any mathematical operations.

If you would like to know more about "floats" and what IEEE
754 is, read this:
http://www.floating-point-gui.de/

Thank you for your interest in PHP.


 [2012-04-26 07:33 UTC] pajoye@php.net
-Status: Open +Status: Not a bug
 [2012-04-26 07:51 UTC] rasmus@php.net
And just for the record, no, the same C code definitely does not return the 
"correct numbers" as you put it:

#include <stdio.h>
#include <math.h>
int main(char *argv[], int argc) {
	double a = 1.2;
	double b = 0.4;
	double v = a/b;
	printf("v(15) = %.15f\n", v);
	printf("v(16) = %.16f\n", v);
	printf("v = %f\n", v);
	printf("floor(v) = %f\n",floor(v));
}

That, I hope you would agree, is the closest thing to the same C code.

% cc a.c -o a -lm
% ./a
v(15) = 3.000000000000000
v(16) = 2.9999999999999996
v = 3.000000
floor(v) = 2.000000

That looks remarkably like the PHP output.
 [2012-04-26 08:16 UTC] martin dot edlman at gmail dot com
Thanks for explanation, I'll modify PHP code to do some round()s or casts to float to get expected results.

I used float instead of double (which uses less decimal points) in my C code, so I got correct results.

#include <math.h>
#include <stdio.h>
int main(char **argv, int argc) {
  float a = 1.2;
  float b = 0.4;
  float v = a/b;
  printf("v(15) = %.15f\n", v);
  printf("v(16) = %.16f\n", v);
  printf("v = %f\n", v);
  printf("floor(v) = %f\n", floor(v));
}

v(15) = 3.000000000000000
v(16) = 3.0000000000000000
v = 3.000000
floor(v) = 3.000000
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 14:01:30 2024 UTC