php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #41907 wrong result from round(64.365,2)
Submitted: 2007-07-05 16:27 UTC Modified: 2007-07-09 10:41 UTC
From: milman at gmx dot de Assigned:
Status: Not a bug Package: *Math Functions
PHP Version: 5.2.3 OS: windows xp
Private report: No CVE-ID: None
 [2007-07-05 16:27 UTC] milman at gmx dot de
Description:
------------
wrong result from round(64.365,2)
should be 64.37 not 64.36

Reproduce code:
---------------
<?
echo "right: round (63.365,2) = " . round (63.365,2) . "<br>\n" ;
echo "wrong: round (64.365,2) = " . round (64.365,2) . "<br>\n" ;
echo "wrong: round (81.365,2) = " . round (81.365,2) . "<br>\n" ;
echo "right: round (82.365,2) = " . round (82.365,2) . "<br>\n" ;
?>

Expected result:
----------------
allway .37 not somtimes .36


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-07-05 16:30 UTC] derick@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.

.
 [2007-07-05 18:48 UTC] milman at gmx dot de
sorry but i can't accept this answer.
for me it seem like, round-problem than bogus and standard answer.

php use common round (Symmetric Arithmetic Rounding)

Decide which is the last digit to keep. 
Increase it by 1 if the next digit is 5 or more (this is called rounding up) 
Leave it the same if the next digit is 4 or less (this is called rounding down) 

and then round (8.155, 2) is 8.16 and not 8.15

sprintf ("%15.8f", 8.155) is 000008.15500000

so it is not a problem from intern representation.

the rounding problem occurs at number_format and sprintf too.

round
 [2007-07-05 18:50 UTC] derick@php.net
php -r 'echo sprintf("%15.20f", 8.155);'

8.15499999999999936051
 [2007-07-05 19:00 UTC] milman at gmx dot de
ok,

but that is the same for other numbers too.

function tround ($r0)
{
  $rr0  = round ($r0,2) ;
  $str1 = sprintf ("%015.20f", $r0) ;

  echo "$r0 : $rr0 $str1<br>\n" ;
}
tround (8.055,2) ;
tround (8.155,2) ;
tround (8.255,2) ;


8.055 : 8.06 8.05499999999999971578
8.155 : 8.15 8.15499999999999936051
8.255 : 8.26 8.25500000000000078160

so i don't understand it.
for me it is a bug.
 [2007-07-09 10:41 UTC] milman at gmx dot de
#ifndef PHP_ROUND_FUZZ
# ifndef PHP_WIN32
#  define PHP_ROUND_FUZZ 0.50000000001
# else
#  define PHP_ROUND_FUZZ 0.5
# endif
#endif

#define PHP_ROUND_WITH_FUZZ(val, places) {			\
	double tmp_val=val, f = pow(10.0, (double) places);	\
	tmp_val *= f;					\
	if (tmp_val >= 0.0) {				\
		tmp_val = floor(tmp_val + PHP_ROUND_FUZZ);	\
	} else {					\
		tmp_val = ceil(tmp_val - PHP_ROUND_FUZZ);	\
	}						\
	tmp_val /= f;					\
	val = !zend_isnan(tmp_val) ? tmp_val : val;	\
}							\

why for windows not 0.50000000001?
i think that would solve the problem.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC