0

I'm in the middle of adding some simple post-code location caching to our system. I've got a "Location" object:

class Location {

    public function __construct(
        public string $postcode, 
        public float $latitude, 
        public float $longitude) {}
}

When I cache this object in redis (hard coded lat/long for testing):

public function getData($postcode) : Location {

    $location = Cache::remember("Location1", 60, function() use ($postcode) {
        return new Location($postcode, 52.7845352, -2.660324);
    });

    return $location;
}

I get excessively long floats in Redis, just wasting space:

"latitude";d:52.78453520000000054324118536897003650665283203125;s:9:"longitude";d:-2.66032400000000013307044355315156280994415283203125

Is there a reason for this I'm missing? How do I stop it?

Thanks.

mkj0
  • 1
  • 1
  • Since no one is reacting to your question, I think it is time to point out that the result in your question is not reproducible. Not because it doesn't happen, but because the code does not represent a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). How do you end up with the output you show us? – KIKO Software Aug 01 '22 at 07:36
  • [this](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) might be related. Also redis is not the culprit here, PHP serialises the floating point number into a string and a IEEE 754 floating point number (with all the limitations and issues in the above question) being converted to an string. If you want to store it verbatim then you should convert it to a string yourself before serialising maybe using the [__serialize()](https://www.php.net/manual/en/language.oop5.magic.php#object.serialize) magic method # – apokryfos Aug 01 '22 at 08:10
  • @apokryfos: I agree this has something to do with how floating point numbers are stored, but I made [a simple reproducible example](https://3v4l.org/O4BiM) and its output doesn't produce additional decimal numbers. Do you have an explanation for this? – KIKO Software Aug 01 '22 at 09:30
  • @KIKOSoftware The only thing I can think of is [serialize_precision](https://www.php.net/manual/en/ini.core.php#ini.serialize-precision) which is a rather obscure php.ini directive. I only found it because your example [for PHP prior to 7.1](https://3v4l.org/O4BiM) shows the extra digits and the change that might have affected that was that in PHP 7.1 the value of that changed to -1 while before it was 17, but this does possibly answer OPs question on how to control the precision of serialised floating point numbers – apokryfos Aug 01 '22 at 09:45
  • @apokryfos: Yes, that would probably allow the OP to control of the output of `serialize()`. Still, it would be nice if the OP could tell us how the result in the question got 48 digits after the decimal point. You have given enough information to investigate this. – KIKO Software Aug 01 '22 at 11:17
  • Hi folks. Thanks for the suggestions. I'll update the question with clearer code for reproducing, and have a look at the things you've suggested. On top of that, what sort of crazy system takes a float of a lower precision, expands it's precision and makes up the extra numbers rather than just zeroing them all? ;-) – mkj0 Aug 02 '22 at 10:36
  • "Precision", as shown, simply depends on the *underlying (binary) format* of the floating point value. When going from a lower to a higher precision format, the extra digits you see are needed to fit the value into the new format. The extra digits give you the best possible approximation of the value that went in. You, as a programmer, have to keep track of the *actual precision* of the values, yourself. When outputing values you can the restrict the precision to that. The precision of a floating point format sets an upper limit on the actual precision. – KIKO Software Aug 02 '22 at 11:00

0 Answers0