rfc:precise_float_value

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
rfc:precise_float_value [2016/05/30 16:27]
bukka Update RFC and add me as an co-author
rfc:precise_float_value [2016/07/09 12:05]
cmb this RFC has already been implemented
Line 1: Line 1:
- 
 ====== PHP RFC: More precise float value handling ====== ====== PHP RFC: More precise float value handling ======
-  * Version: 1.0+  * Version: 1.1
   * Date: 2015-07-30   * Date: 2015-07-30
   * Author: Yasuo Ohgaki <yohgaki@ohgaki.net>, Jakub Zelenka <bukka@php.net>   * Author: Yasuo Ohgaki <yohgaki@ohgaki.net>, Jakub Zelenka <bukka@php.net>
-  * Status: Under Discussion+  * Status: Implemented (PHP 7.1)
   * First Published at: http://wiki.php.net/rfc/precise_float_value   * First Published at: http://wiki.php.net/rfc/precise_float_value
  
Line 11: Line 10:
 This RFC is based on the discussion about displaying float values in json_encode and proposes more precise float value handling overall. This RFC is based on the discussion about displaying float values in json_encode and proposes more precise float value handling overall.
  
-JSON is used to exchange data between systems. Although [[https://tools.ietf.org/html/rfc7159|JSON RFC "6 Numbers"]]  does not require specific implementation for float/int type, float value should be handled as precise as possible by default. +JSON is used to exchange data between systems. Although [[https://tools.ietf.org/html/rfc7159|JSON RFC "6 Numbers"]] does not require specific implementation for float/int type, float value should be handled as precise as possible by default.
  
-Currentlyjson_encode() uses EG(precision) which is set to 14. That means that 14 digits max are used for displaying (printing) the number. IEEE 754 double supports higher precision and serialize()/var_export() uses PG(serialize_precision)=17 to be more precise. Since json_encode() uses EG(precision), json_encode() removes lower digits of fraction parts and destroys original value even if PHP's float could hold more precise float value.+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 higher precision and serialize()/var_export() uses PG(serialize_precision) which set to 17 be default to be more precise. Since json_encode() uses EG(precision), json_encode() removes lower digits of fraction parts and destroys original value even if PHP's float could hold more precise float value.
  
 <code php> <code php>
Line 63: Line 62:
 ===== Proposal ===== ===== Proposal =====
  
-This RFC proposes to introduce EG(precision)=-1 and PG(serialize_precision)=-1 that uses zend_dtoa()'s mode 0 which uses better algorigthm for rounding float numbers (-1 is used to indicate 0 mode).+This RFC proposes to introduce a new setting EG(precision)=-1 and PG(serialize_precision)=-1 that uses zend_dtoa()'s mode 0 which uses better algorigthm for rounding float numbers (-1 is used to indicate 0 mode).
  
-Since JSON is used extensively for web apps, we may have JSON specific INI setting for better compatibility and ease of use. It means to add JSON_G(json.precisionwhich will be used for JSON module specific precision INI setting.+The RFC also proposes changing ini for JSON precision to PG(serialize_precision).
  
 Followings are sample codes and outputs of the proposed patch. Followings are sample codes and outputs of the proposed patch.
Line 76: Line 75:
 ini_set('precision', -1); ini_set('precision', -1);
 ini_set('serialize_precision', -1); ini_set('serialize_precision', -1);
-ini_set('json.precision', -1); 
  
 var_dump($v); var_dump($v);
Line 99: Line 97:
 ini_set('precision', 14); ini_set('precision', 14);
 ini_set('serialize_precision', 17); ini_set('serialize_precision', 17);
-ini_set('json.precision', 14); 
  
 var_dump($v); var_dump($v);
 echo var_export($v, true), PHP_EOL; echo var_export($v, true), PHP_EOL;
 +ini_set('serialize_precision', 14);
 echo json_encode($v), PHP_EOL; echo json_encode($v), PHP_EOL;
 +ini_set('serialize_precision', 17);
 echo $v, PHP_EOL; echo $v, PHP_EOL;
 ?> ?>
Line 121: Line 120:
 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()/serialize(). 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()/serialize().
  
-The BC break could happen only if someone would rely on exact output but that shouldn't be the case. All our existing tests passes even when 0 mode is used.+The BC break could happen only if someone would rely on exact output but that shouldn't be the case. All our existing tests passes when 0 mode is used.
  
 None when old INI value is used. None when old INI value is used.
Line 137: Line 136:
   * 0 mode (EG(precision)= -1) float outputs values rounded to nearest.   * 0 mode (EG(precision)= -1) float outputs values rounded to nearest.
  
-Standard module +Standard module and JSON 
-  * serialize(), var_export() - Use PG(serialize_precision) and 0 mode by default. +  * serialize(), var_export(), json_encode - Use PG(serialize_precision) and 0 mode by default.
- +
-JSON +
-  * json_encode() - Use ini selected from the vote result and 0 mode by default. +
  
 ==== To Opcache ==== ==== To Opcache ====
Line 160: Line 155:
  
 serialize_precision serialize_precision
-  * hardcoded default values : -1 
-  * php.ini-development values : -1 
-  * php.ini-production values : -1 
- 
-json.precision (if accepted) 
   * hardcoded default values : -1   * hardcoded default values : -1
   * php.ini-development values : -1   * php.ini-development values : -1
Line 188: Line 178:
  
  
-===== Proposed Voting Choices =====+===== Voting =====
  
-Requires a 50%+1 majority+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).
  
-There will be two votings+The both votes are straight Yes/No votes.
  
-  * whether to introduce mode 0 as default +<doodle title="Should mode 0 be introduced and set as default for PG(serialize_precision)" auth="bukka" voteType="single" closed="true"> 
-  what precision ini should be used for json (precision, serialize_precision, json.precision).+   Yes 
 +   * No 
 +</doodle> 
 + 
 +<doodle title="Should PG(serialize_precision) be used instead of EG(precision) in json_encode" auth="bukka" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle> 
 + 
 +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://github.com/php/php-src/pull/1455   * https://github.com/php/php-src/pull/1455
 +
 +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://github.com/php/php-src/commit/75b86a2
 +
 After the project is implemented, this section should contain  After the project is implemented, this section should contain 
-  - 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
  
Line 214: Line 218:
  
 ===== 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 (external edit)