#35896 [NEW]: Round() not doing what it says on the tin

2006-01-04 Thread matt at equaliser dot net
From: matt at equaliser dot net
Operating system: Linux
PHP version:  4.4.1
PHP Bug Type: *Math Functions
Bug description:  Round() not doing what it says on the tin

Description:

I know *why* this is happening - so please don't point me to
http://www.php.net/manual/en/language.types.float.php - I'm aware of
this.

This does not change the fact that a pure call to the round() function
using a float value stored in memory can return the wrong result.

The fact that this is easily fixed by rounding to one decimal place
further along the float before performing the actual rounding, simply
makes the continued existence of this bug more baffling. Why doesn't PHP
round() do this internally?

Do all PHP developers need to roll their own round() function if they are
going to guarantee mathematical accuracy?


Reproduce code:
---
?php

$input_value = 45;
$vat = $input_value * .175;
echo $vat . 'br /';
echo round($vat , 2) . 'br /';
echo round(strval($vat) , 2) . 'br /';
echo round(round($vat , 3) , 2) . 'br /';

$input_value2 = 7.875;
echo round($input_value2 , 2) . 'br /';

echo round(7.875 , 2) . 'br /';

echo  $vat - $input_value2;

?


Expected result:

7.875
7.87
7.88
7.88
7.88
7.88
-8.8817841970013E-16

Actual result:
--
7.875
7.88
7.88
7.88
7.88
7.88
-8.8817841970013E-16

-- 
Edit bug report at http://bugs.php.net/?id=35896edit=1
-- 
Try a CVS snapshot (PHP 4.4): 
http://bugs.php.net/fix.php?id=35896r=trysnapshot44
Try a CVS snapshot (PHP 5.1): 
http://bugs.php.net/fix.php?id=35896r=trysnapshot51
Try a CVS snapshot (PHP 6.0): 
http://bugs.php.net/fix.php?id=35896r=trysnapshot60
Fixed in CVS: http://bugs.php.net/fix.php?id=35896r=fixedcvs
Fixed in release: 
http://bugs.php.net/fix.php?id=35896r=alreadyfixed
Need backtrace:   http://bugs.php.net/fix.php?id=35896r=needtrace
Need Reproduce Script:http://bugs.php.net/fix.php?id=35896r=needscript
Try newer version:http://bugs.php.net/fix.php?id=35896r=oldversion
Not developer issue:  http://bugs.php.net/fix.php?id=35896r=support
Expected behavior:http://bugs.php.net/fix.php?id=35896r=notwrong
Not enough info:  
http://bugs.php.net/fix.php?id=35896r=notenoughinfo
Submitted twice:  
http://bugs.php.net/fix.php?id=35896r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=35896r=globals
PHP 3 support discontinued:   http://bugs.php.net/fix.php?id=35896r=php3
Daylight Savings: http://bugs.php.net/fix.php?id=35896r=dst
IIS Stability:http://bugs.php.net/fix.php?id=35896r=isapi
Install GNU Sed:  http://bugs.php.net/fix.php?id=35896r=gnused
Floating point limitations:   http://bugs.php.net/fix.php?id=35896r=float
No Zend Extensions:   http://bugs.php.net/fix.php?id=35896r=nozend
MySQL Configuration Error:http://bugs.php.net/fix.php?id=35896r=mysqlcfg


#35896 [Opn]: Round() not doing what it says on the tin

2006-01-04 Thread matt at equaliser dot net
 ID:   35896
 User updated by:  matt at equaliser dot net
 Reported By:  matt at equaliser dot net
 Status:   Open
 Bug Type: *Math Functions
 Operating System: Linux
 PHP Version:  4.4.1
 New Comment:

Soory - I got the expected result and the actual result interposed in
my previous posting.


Previous Comments:


[2006-01-04 20:30:50] matt at equaliser dot net

Description:

I know *why* this is happening - so please don't point me to
http://www.php.net/manual/en/language.types.float.php - I'm aware of
this.

This does not change the fact that a pure call to the round() function
using a float value stored in memory can return the wrong result.

The fact that this is easily fixed by rounding to one decimal place
further along the float before performing the actual rounding, simply
makes the continued existence of this bug more baffling. Why doesn't
PHP round() do this internally?

Do all PHP developers need to roll their own round() function if they
are going to guarantee mathematical accuracy?


Reproduce code:
---
?php

$input_value = 45;
$vat = $input_value * .175;
echo $vat . 'br /';
echo round($vat , 2) . 'br /';
echo round(strval($vat) , 2) . 'br /';
echo round(round($vat , 3) , 2) . 'br /';

$input_value2 = 7.875;
echo round($input_value2 , 2) . 'br /';

echo round(7.875 , 2) . 'br /';

echo  $vat - $input_value2;

?


Expected result:

7.875
7.87
7.88
7.88
7.88
7.88
-8.8817841970013E-16

Actual result:
--
7.875
7.88
7.88
7.88
7.88
7.88
-8.8817841970013E-16





-- 
Edit this bug report at http://bugs.php.net/?id=35896edit=1


#35896 [Bgs]: Round() not doing what it says on the tin

2006-01-04 Thread matt at equaliser dot net
 ID:   35896
 User updated by:  matt at equaliser dot net
 Reported By:  matt at equaliser dot net
 Status:   Bogus
 Bug Type: Math related
 Operating System: Linux
 PHP Version:  4.4.1
 New Comment:

I *KNOW* floating point numbers have limited precision, but surely the
round() function *IS* supposed to have absolute precision?

this is not a BOGUS bug: float() Still does not do what the
documentation says it does.

There's 2 ways of looking at this; either:

1] round() is incorrectly documented, and it should be made clear that
the round operation is being performed on a number slightly different
that the one apparently represented by the variable.

or:

2] round() should be returning a correctly rounded number which
conforms to the string representation of its input variable.

I can roll a very simple fix myself simply by doing one of the
following:

round((strval($var) , [precision])
- Take the var out of its float representation, instead using its
string representation, then allowing php to convert this string back to
a float before rounding.

round(round($var , [precision+1]) , [precision])
- Round the value to [precision+1] before performing the actual
rounding, thus removing any fuzziness from the end of the float before
actually rounding it.

Both of the above appear to work. What still baffles me is that the PHP
manual implies that it has already taken care of this kind of stuff, and
is going to return me a rounded version of the input I'm giving it,
whereas what it is apparently doing is returning the rounded version of
my $vars current representation in the FPU.

for this situation to persist seems wilfully perverse on Zend's part.
Surely this should either be fixed, or properly documented?


Previous Comments:


[2006-01-04 20:39:19] [EMAIL PROTECTED]

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.





[2006-01-04 20:37:21] matt at equaliser dot net

Soory - I got the expected result and the actual result interposed in
my previous posting.



[2006-01-04 20:30:50] matt at equaliser dot net

Description:

I know *why* this is happening - so please don't point me to
http://www.php.net/manual/en/language.types.float.php - I'm aware of
this.

This does not change the fact that a pure call to the round() function
using a float value stored in memory can return the wrong result.

The fact that this is easily fixed by rounding to one decimal place
further along the float before performing the actual rounding, simply
makes the continued existence of this bug more baffling. Why doesn't
PHP round() do this internally?

Do all PHP developers need to roll their own round() function if they
are going to guarantee mathematical accuracy?


Reproduce code:
---
?php

$input_value = 45;
$vat = $input_value * .175;
echo $vat . 'br /';
echo round($vat , 2) . 'br /';
echo round(strval($vat) , 2) . 'br /';
echo round(round($vat , 3) , 2) . 'br /';

$input_value2 = 7.875;
echo round($input_value2 , 2) . 'br /';

echo round(7.875 , 2) . 'br /';

echo  $vat - $input_value2;

?


Expected result:

7.875
7.87
7.88
7.88
7.88
7.88
-8.8817841970013E-16

Actual result:
--
7.875
7.88
7.88
7.88
7.88
7.88
-8.8817841970013E-16





-- 
Edit this bug report at http://bugs.php.net/?id=35896edit=1