rfc:precise_float_value
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionLast revisionBoth sides next revision | ||
rfc:precise_float_value [2015/08/05 06:49] – Minimize PHP 5.6's changes yohgaki | rfc:precise_float_value [2016/07/09 12:05] – this RFC has already been implemented cmb | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: More precise float value handling ====== | ====== PHP RFC: More precise float value handling ====== | ||
- | * Version: | + | * Version: |
* Date: 2015-07-30 | * Date: 2015-07-30 | ||
- | * Author: Yasuo Ohgaki < | + | * Author: Yasuo Ohgaki < |
- | * Status: | + | * Status: |
* First Published at: http:// | * First Published at: http:// | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | This RFC is based on float like JSON numeric | + | This RFC is based on the discussion |
- | JSON is used to exchange data between systems. Although [[https:// | + | JSON is used to exchange data between systems. Although [[https:// |
- | Currently, json_encode() uses PG(precision) which is 14. IEEE 754 double supports | + | Currently json_encode() uses EG(precision) which is set to 14. That means that 14 digits at most are used for displaying (printing) the number. IEEE 754 double supports |
<code php> | <code php> | ||
Line 40: | Line 40: | ||
</ | </ | ||
- | PHP's float type stores " | + | PHP's float type stores " |
- | Current PHP outputs meaningless values for oversized | + | Current PHP outputs meaningless values for oversized |
<code php> | <code php> | ||
Line 57: | Line 57: | ||
float(0.12345678901234567736988623209981597028672695159912109375) | float(0.12345678901234567736988623209981597028672695159912109375) | ||
</ | </ | ||
+ | |||
+ | That is caused by used mode for double to string conversion. | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | * PHP 7.0: Introduce PG(precision)=-1 and PG(serialize_precision)=-1 that uses zend_dtoa()' | + | This RFC proposes to introduce a new setting EG(precision)=-1 and PG(serialize_precision)=-1 that uses zend_dtoa()' |
- | Since JSON is used extensively | + | The RFC also proposes changing ini for JSON precision to PG(serialize_precision). |
- | * PHP 7.0: Add JSON_G(json_precision) - Add JSON module specific precision INI setting. | + | Followings are sample codes and outputs of the proposed patch. |
- | PHP 5.6's json_encode() uses PG(precision) and could lose floating point number information. | + | NEW behavior |
+ | <code php> | ||
+ | <?php | ||
+ | $v = 10.0000000000001; | ||
- | * PHP 5.6: Make json_encode() | + | ini_set(' |
+ | ini_set(' | ||
+ | |||
+ | var_dump($v); | ||
+ | echo var_export($v, | ||
+ | echo json_encode($v), | ||
+ | echo $v, PHP_EOL; | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | float(10.0000000000001) | ||
+ | 10.0000000000001 | ||
+ | 10.0000000000001 | ||
+ | 10.0000000000001 | ||
+ | |||
+ | |||
+ | |||
+ | OLD behavior | ||
+ | <code php> | ||
+ | <?php | ||
+ | $v = 10.00000000000001; | ||
+ | |||
+ | ini_set(' | ||
+ | ini_set(' | ||
+ | |||
+ | var_dump($v); | ||
+ | echo var_export($v, | ||
+ | ini_set(' | ||
+ | echo json_encode($v), PHP_EOL; | ||
+ | ini_set('serialize_precision', 17); | ||
+ | echo $v, PHP_EOL; | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | float(10) | ||
+ | 10.000000000000011 | ||
+ | 10 | ||
+ | 10 | ||
+ | |||
+ | |||
+ | Please note that IEEE float cannot store exactly precise values. e.g. Result of " | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | None because | + | Setting mode 0 as default can mean that the rounding will be more precise which also means that the rounding might be different in var_export()/ |
+ | |||
+ | The BC break could happen only if someone would rely on exact output but that shouldn' | ||
+ | |||
+ | None when old INI value is used. | ||
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
- | PHP 7.0.0 - 0 mode and JSON_G(json_precision) | + | * PHP 7.1 |
- | PHP 5.6.x - 0 mode. JSON uses PG(serialize_precision) for float precision. | + | |
===== RFC Impact ===== | ===== RFC Impact ===== | ||
Line 86: | Line 134: | ||
==== To Existing Extensions ==== | ==== To Existing Extensions ==== | ||
PHP overall | PHP overall | ||
- | * 0 mode float outputs values rounded to nearest. | + | |
- | + | ||
- | Standard module | + | |
- | * serialize(), | + | |
- | + | ||
- | JSON | + | |
- | * json_encode() - PHP7.0: Use 0 mode. PHP5.6: Use PG(serialize_precision) | + | |
- | + | ||
- | WDDX? | + | |
- | + | ||
- | XML_RPC? | + | |
+ | Standard module and JSON | ||
+ | * serialize(), | ||
==== To Opcache ==== | ==== To Opcache ==== | ||
Line 114: | Line 154: | ||
* php.ini-production values : 14 Unmodified | * php.ini-production values : 14 Unmodified | ||
- | serialize_precision(PHP5.6) | + | serialize_precision |
- | * hardcoded default values : 17 Unmodified | + | |
- | * php.ini-development values : 17 Unmodified | + | |
- | * php.ini-production values : 17 Unmodified | + | |
- | + | ||
- | serialize_precision(PHP7) | + | |
- | * hardcoded default values : -1 | + | |
- | * php.ini-development values : -1 | + | |
- | * php.ini-production values : -1 | + | |
- | + | ||
- | json_precision(NEW - PHP7 only) | + | |
* hardcoded default values : -1 | * hardcoded default values : -1 | ||
* php.ini-development values : -1 | * php.ini-development values : -1 | ||
Line 137: | Line 167: | ||
PHP uses " | PHP uses " | ||
+ | |||
===== Future Scope ===== | ===== Future Scope ===== | ||
- | | + | WDDX |
+ | | ||
- | ===== Proposed Voting Choices ===== | + | XML_RPC |
+ | * xmlrpc_encode() - Use PG(serialize_precision) and 0 mode. It uses EG(precision) currently. | ||
- | Requires a 50%+1 majority (see [[voting]]) | ||
- | <doodle title=" | + | ===== Voting ===== |
- | * Yes | + | |
- | * No | + | |
- | </ | + | |
- | . | + | Requires a 2/3 majority for the first vote (mode 0 to become default for serialize precision) and 50%+1 majority for the second vote (changing default for json). |
- | <doodle title=" | + | The both votes are straight Yes/No votes. |
+ | |||
+ | <doodle title=" | ||
* Yes | * Yes | ||
* No | * No | ||
</ | </ | ||
- | . | + | <doodle title=" |
- | + | ||
- | <doodle title=" | + | |
* Yes | * Yes | ||
* No | * No | ||
</ | </ | ||
+ | The votes started on 2016-06-12 at 19:00 UTC and ended on 2016-06-19 at 19:00 UTC. | ||
===== Patches and Tests ===== | ===== Patches and Tests ===== | ||
+ | |||
+ | The initial PR can be found here: | ||
* https:// | * https:// | ||
+ | |||
+ | Note that the PR is currently outdated but it will be updated if the RFC is accepted. | ||
===== Implementation ===== | ===== Implementation ===== | ||
+ | |||
+ | Merged into php-src for PHP 7.1: https:// | ||
+ | |||
After the project is implemented, | After the project is implemented, | ||
- | - the version(s) it was merged to | ||
- | - a link to the git commit(s) | ||
- a link to the PHP manual entry for the feature | - a link to the PHP manual entry for the feature | ||
===== References ===== | ===== References ===== | ||
- | https:// | + | * https:// |
+ | * https:// | ||
+ | * http:// | ||
===== Rejected Features ===== | ===== Rejected Features ===== | ||
- | Keep this updated with features that were discussed on the mail lists. | + | |
+ | None |
rfc/precise_float_value.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1