summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/tests/dval_to_lval_32.phpt3
-rw-r--r--Zend/zend_operators.h6
2 files changed, 8 insertions, 1 deletions
diff --git a/Zend/tests/dval_to_lval_32.phpt b/Zend/tests/dval_to_lval_32.phpt
index ddb16ccb82..f2acc39f51 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 a3a432ff15..a82c14b8c2 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;