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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: milman at gmx dot de
New email:
PHP Version: OS:

 

 [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 11:01:30 2024 UTC