Browse Source

fix & unify double-to-string conversion utils

PHAR_1_2
Antony Dovgal 20 years ago
parent
commit
a63ee1b323
  1. 66
      Zend/tests/double_to_string.phpt
  2. 20
      Zend/zend_operators.c
  3. 9
      Zend/zend_strtod.c

66
Zend/tests/double_to_string.phpt

@ -0,0 +1,66 @@
--TEST--
double to string conversion tests
--FILE--
<?php
$doubles = array(
290000000000000000,
290000000000000,
29000000000000,
29000000000000.123123,
29000000000000.7123123,
29000.7123123,
239234242.7123123,
0.12345678901234567890,
10000000000000,
100000000000000,
1000000000000000001,
100000000000001,
10000000000,
999999999999999,
9999999999999999,
(float)0
);
foreach ($doubles as $d) {
var_dump((string)$d);
}
echo "Done\n";
?>
--EXPECTF--
string(7) "2.9E+17"
string(7) "2.9E+14"
string(14) "29000000000000"
string(14) "29000000000000"
string(14) "29000000000001"
string(13) "29000.7123123"
string(15) "239234242.71231"
string(16) "0.12345678901235"
string(14) "10000000000000"
string(7) "1.0E+14"
string(7) "1.0E+18"
string(7) "1.0E+14"
string(11) "10000000000"
string(7) "1.0E+15"
string(7) "1.0E+16"
string(1) "0"
Done
--UEXPECTF--
unicode(7) "2.9E+17"
unicode(7) "2.9E+14"
unicode(14) "29000000000000"
unicode(14) "29000000000000"
unicode(14) "29000000000001"
unicode(13) "29000.7123123"
unicode(15) "239234242.71231"
unicode(16) "0.12345678901235"
unicode(14) "10000000000000"
unicode(7) "1.0E+14"
unicode(7) "1.0E+18"
unicode(7) "1.0E+14"
unicode(11) "10000000000"
unicode(7) "1.0E+15"
unicode(7) "1.0E+16"
unicode(1) "0"
Done

20
Zend/zend_operators.c

@ -769,10 +769,24 @@ static UChar* zend_u_format_gdouble(double dnum, int ndigit, UChar *result)
p1 = zend_u_format_double(dnum, ndigit, &decpt, &sign, 1, buf1);
p2 = result;
if (sign)
if (sign) {
*p2++ = (UChar) 0x2d /*'-'*/;
for (i = ndigit - 1; i > 0 && p1[i] == (UChar) 0x30 /*'0'*/; i--)
ndigit--;
}
/* if decimal point position is less than precision, cut zeros only in fractional part */
if (decpt <= ndigit) {
i = ndigit - 1;
while (i > 0 && i >= decpt && p1[i] == (UChar) 0x30 /*'0'*/) {
ndigit--;
i--;
}
} else {
/* otherwise cut all trailing zeros */
for (i = ndigit - 1; i > 0 && p1[i] == (UChar) 0x30 /*'0'*/; i--) {
ndigit--;
}
}
if ((decpt >= 0 && decpt - ndigit > 4)
|| (decpt < 0 && decpt < -3)) { /* use E-style */
decpt--;

9
Zend/zend_strtod.c

@ -1719,7 +1719,14 @@ ZEND_API char * zend_dtoa(double _d, int mode, int ndigits, int *decpt, int *sig
if (value(d) > 0.5 + value(eps))
goto bump_up;
else if (value(d) < 0.5 - value(eps)) {
while(*--s == '0');
/* cut ALL traling zeros only if the number of chars is greater than precision
* otherwise cut only extra zeros
*/
if (k < ndigits) {
while(*--s == '0' && (s - s0) > k);
} else {
while(*--s == '0');
}
s++;
goto ret1;
}

Loading…
Cancel
Save