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
Next revision Both sides next 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/06/19 18:41]
bukka Close vote
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: Accepted
   * 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 =====
Line 214: Line 217:
  
 ===== 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)