php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #34427 round function bug
Submitted: 2005-09-08 14:24 UTC Modified: 2010-03-13 20:00 UTC
From: lukasz at knasiecki dot com Assigned:
Status: Not a bug Package: Math related
PHP Version: 5.0.5 OS: Windows XP
Private report: No CVE-ID: None
 [2005-09-08 14:24 UTC] lukasz at knasiecki dot com
Description:
------------
Round function works with errors.

Reproduce code:
---------------
echo '<br>'.round(8.055, 2); 
echo '<br>'.round(8.155, 2); 
echo '<br>'.round(8.255, 2); 

Expected result:
----------------
echo '<br>'.round(8.055, 2); //gives 8.06
echo '<br>'.round(8.155, 2); //gives 8.16
echo '<br>'.round(8.255, 2); //gives 8.26


Actual result:
--------------
echo '<br>'.round(8.055, 2); //gives 8.06
echo '<br>'.round(8.155, 2); //gives 8.15 !!!
echo '<br>'.round(8.255, 2); //gives 8.26


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-09-08 14:32 UTC] tony2001@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://docs.sun.com/source/806-3568/ncg_goldberg.html
 
Thank you for your interest in PHP.


 [2005-09-08 14:45 UTC] lukasz at knasiecki dot com
Still, I am sure this is a bug. No software I use (Excel, Shopping program) produces such results, like PHP

 echo '<br>'.round(0.155*1, 2);  >> gives 0,16
 echo '<br>'.round(8.155*1, 2);  >> gives 8,15
 [2010-03-12 04:01 UTC] sonicpr at bol dot com dot br
<?php

function myround($n,$p=0) {
	$div = pow(10,$p);
	$sign = ($n > 0) ? +0.5 : -0.5;
	return floor(0.000000000001 + ($sign + $div * $n))/$div;
}

echo round(9.5), ' => ', myround(9.5), chr(10); // 10 => 10
echo round(9.95,1), ' => ', myround(9.95,1), chr(10); // 10 => 10
echo round(9.995,2), ' => ', myround(9.995,2), chr(10); // 9.99 => 10
echo round(9.9995,3), ' => ', myround(9.9995,3), chr(10); // 10 => 10
echo round(9.99995,4), ' => ', myround(9.99995,4), chr(10); // 10 => 10

echo round(-9.5), ' => ', myround(-9.5), chr(10); // -10 => -10
echo round(-9.95,1), ' => ', myround(-9.95,1), chr(10); // -10 => -10
echo round(-9.995,2), ' => ', myround(-9.995,2), chr(10); // -9.99 => -10
echo round(-9.9995,3), ' => ', myround(-9.9995,3), chr(10); // -10 => -10
echo round(-9.99995,4), ' => ', myround(-9.99995,4), chr(10); // -10 => -10

echo round(8.155, 2), ' => ', myround(8.155, 2), chr(10); // 8.155 => 8.16
/*
PHP 5.2.6-1+lenny6 with Suhosin-Patch 0.9.6.2 (cli) (built: Feb  9 2010 03:05:13)
Copyright (c) 1997-2008 The PHP Group
*/

?>
 [2010-03-13 20:00 UTC] rasmus@php.net
From your original report 8.155 can't actually be represented accurately 
internally in IEEE-754.  It is actually stored as 8.15499999999999 so when you 
round that to 2 decimal places you are going to end up with 8.15.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Nov 05 13:01:29 2024 UTC