]> granicus.if.org Git - php/commitdiff
fix & unify double-to-string conversion utils
authorAntony Dovgal <tony2001@php.net>
Thu, 19 Apr 2007 09:30:10 +0000 (09:30 +0000)
committerAntony Dovgal <tony2001@php.net>
Thu, 19 Apr 2007 09:30:10 +0000 (09:30 +0000)
Zend/tests/double_to_string.phpt [new file with mode: 0644]
Zend/zend_operators.c
Zend/zend_strtod.c

diff --git a/Zend/tests/double_to_string.phpt b/Zend/tests/double_to_string.phpt
new file mode 100644 (file)
index 0000000..461c03f
--- /dev/null
@@ -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
index 58bf8f6ebbb86521c3afad83922c884129a7cdcb..8b142e62868472a16ef21756947c17fb86c06197 100644 (file)
@@ -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--;
index 0328416dfe3cbf9ac3c2c2154f8a20756539d5a2..23dd743ef9229b943e94c6bb2f8fe6f776f2d173 100644 (file)
@@ -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;
                                        }