com php-src: Fix rounding of zend_dval_to_lval: Zend/ tests/dval_to_lval_32.phpt Zend/zend_operators .h
| From: | Gustavo André dos Santos Lopes | Date: | Sat, 23 Feb 2013 16:55:50 +0000 |
| Subject: | com php-src: Fix rounding of zend_dval_to_lval: Zend/ tests/dval_to_lval_32.phpt Zend/zend_operators .h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-71292@lists.php.net to get a copy of this message | ||
Commit: a86fcfbc1d397e4a716c65455ca09bb04e6439cf
Author: Gustavo Lopes <glopes@nebm.ist.utl.pt> Sat, 23 Feb 2013 00:41:39 +0100
Parents: 77566edbafb969e166239b3fbc929588c6630ee9
Branches: PHP-5.5 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=a86fcfbc1d397e4a716c65455ca09bb04e6439cf
Log:
Fix rounding of zend_dval_to_lval
Now rounding is always towards zero; the rounding can be though as if
occurring on the original double. Only relevant for the 32-bit long
variant.
Changed paths:
M Zend/tests/dval_to_lval_32.phpt
M Zend/zend_operators.h
Diff:
diff --git a/Zend/tests/dval_to_lval_32.phpt b/Zend/tests/dval_to_lval_32.phpt
index ddb16cc..f2acc39 100644
--- a/Zend/tests/dval_to_lval_32.phpt
+++ b/Zend/tests/dval_to_lval_32.phpt
@@ -15,6 +15,8 @@ if (PHP_INT_SIZE != 4)
-3999999999999999475712.,
-3999999999999998951424.,
];
+ /* see if we're rounding negative numbers right */
+ $values[] = -2147483649.8;
foreach ($values as $v) {
var_dump((int)$v);
@@ -27,3 +29,4 @@ int(-2055733248)
int(-2055208960)
int(-2054684672)
int(-2054160384)
+int(2147483647)
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index a3a432f..a82c14b 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -77,7 +77,9 @@ static zend_always_inline long zend_dval_to_lval(double d)
dmod = fmod(d, two_pow_32);
if (dmod < 0) {
- dmod += two_pow_32;
+ /* we're going to make this number positive; call ceil()
+ * to simulate rounding towards 0 of the negative number */
+ dmod = ceil(dmod) + two_pow_32;
}
return (long)(unsigned long)dmod;
}
@@ -93,6 +95,8 @@ static zend_always_inline long zend_dval_to_lval(double d)
dmod = fmod(d, two_pow_64);
if (dmod < 0) {
+ /* no need to call ceil; original double must have had no
+ * fractional part, hence dmod does not have one either */
dmod += two_pow_64;
}
return (long)(unsigned long)dmod;