1

I have the following php snippet

$newData = serialize(array('ep' => 50733372961735.4));
echo "New data: " . print_r($newData, 1);

Output:

New data: a:1:{s:2:"ep";d:5.07333729617E+13;}

But I would like the float value as it is and not E+13.

What could I do without having to make drastic changes as this is just an example. In my actual code the 'ep' value could be inside a complex array hierarchy

Anand
  • 4,182
  • 6
  • 42
  • 54
  • Store it as a string if you want it as accurate as you provide it (or use a maths library). PHP only has a finite accuracy when it comes to floats. – apokryfos May 22 '18 at 16:17
  • i tried settype - which didnt work as it rounded it down – Anand May 22 '18 at 16:18
  • `serialize(array('ep' => "50733372961735.4"));` fun fact this is not a problem on all machines. Check http://sandbox.onlinephpfunctions.com/code/61556f1a7d15a8db54d8cd1c4e9cbd4a4722e450 – apokryfos May 22 '18 at 16:19
  • You can either raise the precision `ini_set( 'precision', 30 );` or us a string. – MonkeyZeus May 22 '18 at 16:22

3 Answers3

1

Firstly, a general note: serialize should never be used on data that could be manipulated in any way. It's useful for things like session data and caches, but should not be relied on for transporting data between applications or data storage. In many cases, you're better off using a standard serialization format like JSON.

You also certainly shouldn't care what the serialized string looks like - the only thing you should do with that string is pass it back to unserialize(). So the fact that there is E+13 is not a problem if the actual value it gives back when you unserialize is the one you wanted.

However, it's clear in your example that you have lost precision - the last digits are ...29617 rather than ...29617354 - so back to the point: there is a PHP setting serialize_precision, described in the manual here. It's default value has varied over the years, but setting it to an explicit value other than -1 will serialize floats with that number of significant figures:

ini_set('serialize_precision', 2);
echo serialize(50733372961735.4), PHP_EOL;
// d:5.1E+13;

ini_set('serialize_precision', 20);
echo serialize(50733372961735.4), PHP_EOL;
// d:50733372961735.398438;

Note that the first example has clearly thrown away information, whereas the second has actually stored more precision than you realised you had - because of the inaccuracy of storing decimals in binary floating point format.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
0

The problem is not the serialize at all!

it's numbers in general.

$num = 50733372961735.4;
print($num);

=> 50733372961735

to "solve" this problem you can use:

ini_set('serialize_precision', 15);
I-V
  • 725
  • 4
  • 10
  • Sorry, but this is wrong on both counts: `serialize` *is* explicitly choosing a precision to write the float with, and it is *not* governed by the `precision` setting, but a separate `serialize_precision` setting. – IMSoP May 22 '18 at 16:28
  • try it and you will see I'm right. the default (after php 5.4.0 is 17). he needs only 15. so the thing that round it is not the serializer – I-V May 22 '18 at 16:37
  • What you have posted is true, but *it is not the issue the OP is having*. They are using `serialize`, and having problems with the accuracy of the serialized form, which is unrelated to the accuracy used when printing the number. – IMSoP May 22 '18 at 16:38
  • again, you are wrong. the default for serialize_precision is 17. he need only 15. the precision is (by default) less than 15 so it rounds it – I-V May 22 '18 at 16:41
  • So what rounds it? The output shown in the question is *the result of `serialize`*, so has been rounded only by `serialize`, which obeys `serialize_precision`. The `precision` setting is used only when *displaying* numbers, so is irrelevant to the `serialize` output. – IMSoP May 22 '18 at 16:44
  • you are right, i looked at the wrong output. I fixed it. – I-V May 22 '18 at 16:45
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/171563/discussion-between-i-v-and-imsop). – I-V May 22 '18 at 16:54
-1

I just executed your code on www.writephponline.com

I got the below value if I did not put your value in string :- $newData = serialize(array('ep' => 50733372961735.4));

New data: a:1:{s:2:"ep";d:50733372961735.398;}

and this after adding it in string :- $newData = serialize(array('ep' => '50733372961735.4'));

New data: a:1:{s:2:"ep";s:16:"50733372961735.4";}

  • Yes, the precision depends on PHP version and a runtime setting, so different environments will behave differently. That doesn't solve the problem though. – IMSoP May 22 '18 at 16:28