iliaa           Wed Oct 29 20:03:34 2008 UTC

  Modified files:              (Branch: PHP_5_3)
    /php-src/ext/standard       math.c 
  Log:
  Fixed bug #42294 (Unified solution for round() based on C99 round)
  [DOC] New implementation of round() to work-around inconsistencies for win32
  and 64 bit platforms.
  
  This solution is very roughly based on BSD's implmentation of round(), which
  itself is an implementation of C99 standard. We take the absolute value of 
number
  we want to round time the 10 to the power of the number of decimal spaces we 
are 
  rounding to. The resulting value is rounded up and the pre-rounded value is 
  subtracted from it. If the difference is greater then 0.5000000001 we round 
up,
  otherwise we round down.
  
  
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/math.c?r1=1.131.2.2.2.6.2.9&r2=1.131.2.2.2.6.2.10&diff_format=u
Index: php-src/ext/standard/math.c
diff -u php-src/ext/standard/math.c:1.131.2.2.2.6.2.9 
php-src/ext/standard/math.c:1.131.2.2.2.6.2.10
--- php-src/ext/standard/math.c:1.131.2.2.2.6.2.9       Tue Oct 21 22:08:37 2008
+++ php-src/ext/standard/math.c Wed Oct 29 20:03:34 2008
@@ -19,7 +19,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: math.c,v 1.131.2.2.2.6.2.9 2008/10/21 22:08:37 lbarnaud Exp $ */
+/* $Id: math.c,v 1.131.2.2.2.6.2.10 2008/10/29 20:03:34 iliaa Exp $ */
 
 #include "php.h"
 #include "php_math.h"
@@ -29,26 +29,60 @@
 #include <float.h>
 #include <stdlib.h>
 
-#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;     \
-}                                                      \
+/*
+ * Pertains to some of the code found in the php_round() function
+ * Ref: http://www.freebsd.org/cgi/query-pr.cgi?pr=59797
+ * 
+ * Copyright (c) 2003, Steven G. Kargl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+static double php_round(double val, int places) {
+       double t;
+       double f = pow(10.0, (double) places);
+       double x = val * f;
+
+       if (zend_isinf(x) || zend_isnan(x)) {
+               return val;
+       }
+
+       if (x >= 0.0) {
+               t = ceil(x);
+               if ((t - x) > 0.50000000001) {
+                       t -= 1.0;
+               }
+       } else {
+               t = ceil(-x);
+               if ((t + x) > 0.50000000001) {
+                       t -= 1.0;
+               }
+               t = -t; 
+       }
+       x = t / f;
 
+       return !zend_isnan(x) ? x : t;
+}
 
 /* {{{ php_asinh
 */
@@ -204,7 +238,7 @@
 
                case IS_DOUBLE:
                        return_val = (Z_TYPE_PP(value) == IS_LONG) ? 
(double)Z_LVAL_PP(value) : Z_DVAL_PP(value);
-                       PHP_ROUND_WITH_FUZZ(return_val, places);
+                       return_val = php_round(return_val, places);
                        RETURN_DOUBLE(return_val);
                        break;
 
@@ -941,7 +975,7 @@
        }
 
        dec = MAX(0, dec);
-       PHP_ROUND_WITH_FUZZ(d, dec);
+       d = php_round(d, dec);
 
        tmplen = spprintf(&tmpbuf, 0, "%.*F", dec, d);
 



-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to