Req #68456 [Wfx]: json_decode should be able to treat all numbers as strings

From: Date: Sun, 15 Mar 2015 19:42:53 +0000
Subject: Req #68456 [Wfx]: json_decode should be able to treat all numbers as strings
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-191407@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=68456&edit=1 ID: 68456 User updated by: admin at bittylicious dot com Reported by: admin at bittylicious dot com Summary: json_decode should be able to treat all numbers as strings Status: Wont fix Type: Feature/Change Request Package: JSON related Operating System: Linux Wheezy PHP Version: 5.4.35 Assigned To: bukka Block user comment: N Private report: N New Comment: I do understand what you're saying, but my feature request is under the assumption you never ever need to convert this to a float, and my real life use case is indeed this situation. Simplifying things, let's imagine a JSON service that simply multiplies a number by two. You would pass in: {"val":1234567890.12345678} But you would have no way to even pass this to bcmul (which I believe works on strings) without losing precision even if bcmul needn't have any precision issues. Consider another service. This simply forwards "val" onwards perhaps with a hash signature or something. Consider this a "signing service". It cannot read this 'val' value without losing precision, when I think it should be possible to interpret this as a string. This is actually more similar to my use case, in other words, using JSON really as a transport mechanism and not manipulating these numbers within the PHP script. Previous Comments: ------------------------------------------------------------------------ [2015-03-15 18:16:55] bukka@php.net The problem is that the precision will be lost anyway. Most of all you loose the precision immediately when you save it as a float. Basically this: $a = 1234567890.12345678; will loose the precision. You will be never able to get it back. I hope that this example will explain it a bit more: http://3v4l.org/r2uGa Mind that string conversion in json would do the same thing as using (string). Otherwise it wouldn't respect precision ini. Can you see what I mean now? ------------------------------------------------------------------------ [2015-03-15 17:27:02] admin at bittylicious dot com That's my point precisely though - I don't want to save the number as a float, I want to save it as a string. That way, I can either record it somewhere or do some bcmath on it. JSON is really regularly used as a transport stream where data isn't manipulated. In my real life example, I'm passing one value, via JSON, to a totally different process. I don't do any math on the number at all, but the precision is lost. This is why I want to treat it as a string but it's impossible to do this without manipulating the JSON itself before passing it to json_decode. Please reopen this if you agree. ------------------------------------------------------------------------ [2015-03-15 16:53:05] bukka@php.net The problem is that this number will never get saved with the full precision. You can influence the number of visible decimal places with setting ini precision as it is in http://3v4l.org/80iCh However as you can see the number is rounded because the internal float representation (C double type) cannot contain the whole number. So this is not JSON related. and any conversion to string can't fixed. The thing is that json_decode is using normal string conversion. So this can't be fixed in the JSON. I'd recommend you not to save the number to the the float at all but represent it as a string. ------------------------------------------------------------------------ [2014-11-19 22:18:56] admin at bittylicious dot com Description: ------------ There should be an option that can be passed to json_decode that will allow numbers to be handled as strings. This is because some numbers can not be represented in a float properly. In reality, JSON is often used as a transport layer, and it's very useful to keep this accuracy. One example in practice where this has caused issues is when dealing with Dogecoin (a Bitcoin derivative). Dogecoin has eight decimal places, and because each Dogecoin is worth only a tiny fraction of a cent, they can often be represented as tens or hundreds of millions of Dogecoins. When you're dealing with finance, it's essential not to lose precision. The only workaround I have is to use a complicated preg_replace to add quotes to the original JSON string, which is nasty. Test script: --------------- <?php print_r(json_decode('{"test":1234567890.12345678}')); ?> Output: stdClass Object ( [test] => 1234567890.1235 ) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=68456&edit=1

« previous php.bugs (#191407) next »