|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-07-31 05:53 UTC] rainer dot jung at kippdata dot de
Description: ------------ A precision problem in float makes a huge number of tests fail. It could well be, that this is a platform specific failure (Solaris 10 Sparc, 32 Bit build). Below you will find a test case with correct result returned from version 5.6.11 and wrong result from 7.0.0 Beta 2. Test script: --------------- <?php $var = 29000000; var_dump($var); $var = 290000000; var_dump($var); $var = 2900000000; var_dump($var); $var = 29000000000; var_dump($var); $var = 290000000000; var_dump($var); $var = 2900000000000; var_dump($var); $var = 29000000000000; var_dump($var); $var = 290000000000000; var_dump($var); $var = 2900000000000000; var_dump($var); ?> Expected result: ---------------- int(29000000) int(290000000) float(2900000000) float(29000000000) float(290000000000) float(2900000000000) float(29000000000000) float(2.9E+14) float(2.9E+15) Actual result: -------------- int(29000000) int(290000000) float(2899998720) float(28999991296) float(289999945728) float(2899998408704) float(28999988281344) float(2.899999499223E+14) float(2.8999984254812E+15) Patches70173_Standalone_Reproduction.c (last revision 2015-08-08 21:55 UTC by rainer dot jung at kippdata dot de)Pull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 07:00:01 2025 UTC |
Concerning zend_strtod(): - I first tried the original library available under www.netlib.org/fp. It didn't show the problem. - I then tried to shrink the delta between the PHP copy and the original and ended up with a test case, that doesn't show the problem even with PHP zend_strtod(). So it seems it is something in PHP before the calls to zend_strtod(), or the problem is in the output rendering of the float. Here's my test: 1) Create a file dtoa-main.c containing: #include <stdio.h> #include <zend_strtod.h> int main() { fprintf(stdout, "%f\n", zend_strtod("29000000", NULL)); fprintf(stdout, "%f\n", zend_strtod("290000000", NULL)); fprintf(stdout, "%f\n", zend_strtod("2900000000", NULL)); fprintf(stdout, "%f\n", zend_strtod("29000000000", NULL)); fprintf(stdout, "%f\n", zend_strtod("290000000000", NULL)); fprintf(stdout, "%f\n", zend_strtod("2900000000000", NULL)); fprintf(stdout, "%f\n", zend_strtod("29000000000000", NULL)); fprintf(stdout, "%f\n", zend_strtod("290000000000000", NULL)); fprintf(stdout, "%f\n", zend_strtod("2900000000000000", NULL)); } The numbers are the same as in the test.php I originally use to produce the problem. Now compile this snippet against the original zend_strtod.o object file: solaris10.sparc apache% gcc -I /path/to/php/bldir/Zend -I /path/to/php/bldir/TSRM -I /path/to/php/bldir -Wl,-z -Wl,nodefs -o dtoa-test dtoa-main.c /path/to/php/bldir/Zend/.libs/zend_strtod.o The "-z nodefs" linker argument is only needed, because the object file references the zend_error_noreturn symbol, which is not used in this test case. I didn't want to soak in many more object files. Now run the binary: ./dtoa-test 29000000.000000 290000000.000000 2900000000.000000 29000000000.000000 290000000000.000000 2900000000000.000000 29000000000000.000000 290000000000000.000000 2900000000000000.000000 So the float seems to be OK.