[php-maint] Bug#603292: Bug#603292: libapache2-mod-php5: PHP5 does not round correctly

Ondřej Surý ondrej at debian.org
Mon Nov 15 06:52:27 UTC 2010


Bob,

thanks for comprehensive explanation. Would you be willing to put this
information to f.e. http://wiki.debian.org/PHP/Rounding and link it
from http://wiki.debian.org/PHP (or just in
http://wiki.debian.org/PHP/Rounding), so it doesn't disappear when
this bug is archived?

Ondrej

On Mon, Nov 15, 2010 at 06:13, Bob Proulx <bob at proulx.com> wrote:
> Markus Knaup wrote:
>> PHP5 does not round correctly.
>> echo round(1.025, 2) . "<br />";
>
> Note that this is the same behavior as C's printf.  Also the shell's
> printf which makes that behavior available to the command line
> produces the same behavior.
>
>  $ printf "%.2f\n" 1.025
>  1.02
>
> But it just didn't seem satisfying to say that it isn't a bug in PHP
> because that is just the way floating point computer engines work.
> But that is basically the reason.  That is the way floating point
> works on machines.  But being unsatisfying I wanted to add some more
> information about the problem.
>
> For the underlying reasons you need to look at the encoded binary
> values.  A typical issue is that exact terminating decimal fractions
> may not have an exact binary representation.  Therefore converting
> from decimal to binary creates an error.
>
>  1.020 => 1.00000101000111101011100001010001111010111000010100011110101110...
>  1.025 => 1.00000110011001100110011001100110011001100110011001100110011001...
>  1.030 => 1.00000111101011100001010001111010111000010100011110101110000101...
>
> Since there are an infinite number of digits needed this can't be used
> without reducing the number of digits in the calculation.  That means
> that floating point operations routinely introduce errors into
> calculations.  As to the exact details of rounding fractional digits I
> have always avoided needing to know that information.  I have avoided
> it because when I needed an exact value I knew about the problems and
> instead used scaled integers.  And so I can't give a better
> explanation now.  Only a recommendation to avoid it too.
>
> Remember that floating point is only an approximation of reality.  For
> more exact answers you may want to use binary coded decimal or scaled
> integers.  This example is a good one to show why floating point isn't
> used for monetary transactions.  My personal history is with CAD/EDA
> software and in that problem domain most software uses scaled integers
> to avoid these types of errors.
>
> There have been recent changes in the way PHP handles rounding.
> The upstream PHP documentation lists:
>
>  5.3.0  The mode parameter was introduced.
>
>  5.2.7  The inner workings of round() was changed to conform to the
>         C99 standard.
>
> In 5.3.0 and later (Sid or Squeeze) the mode parameter gives you some
> control over rounding.
>
>  $ php -r 'echo round(1.025,2,PHP_ROUND_HALF_UP) . "\n";'
>  1.03
>
> Also the default rounding mode has changed too.
>
>  $ php -r 'echo round(1.025,2) . "\n";'
>  1.03
>
> Hope that helps,
> Bob
>
> P.S. Here are some useful references.
>
>  http://en.wikipedia.org/wiki/Double_precision_floating-point_format
>
>  http://en.wikipedia.org/wiki/Floating_point#Rounding_modes
>
>  http://en.wikipedia.org/wiki/Binary_numeral_system#Decimal
>
>  http://en.wikipedia.org/wiki/Binary_numeral_system#Representing_real_numbers
>
>  http://cs.furman.edu/digitaldomain/more/ch6/dec_frac_to_bin.htm
>
>  http://www.exploringbinary.com/binary-converter/
>
>
>
> _______________________________________________
> pkg-php-maint mailing list
> pkg-php-maint at lists.alioth.debian.org
> http://lists.alioth.debian.org/mailman/listinfo/pkg-php-maint
>



-- 
Ondřej Surý <ondrej at sury.org>
http://blog.rfc1925.org/





More information about the pkg-php-maint mailing list