Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP float broken after use of pack function #8398

Closed
mattrx opened this issue Mar 10, 2021 · 3 comments
Closed

PHP float broken after use of pack function #8398

mattrx opened this issue Mar 10, 2021 · 3 comments
Assignees

Comments

@mattrx
Copy link

mattrx commented Mar 10, 2021

We updated or PHP application to use version 3.15.5 today and found that some of our tests are failing because float values are not what we expected. We traced it to the change from #8187, before the change everything was fine.

We think that the use of unpack("f", pack("f", $var))[1] is problematic because it breaks with even very simple numbers... at least in our environment (debian:buster-slim with php7.3). According to the php manual the pack/unpack functions are machine dependent.

var_dump(unpack("f", pack("f", 2.34)));
array(1) {
  [1]=>
  float(2.3399999141693115)
}

Any ideas?

@acozzette
Copy link
Member

I am not very familiar with this issue but my understanding was that #8187 corrected a case where we were being more precise than we were supposed to be, so if you're seeing a loss of precision then that could be an expected consequence of the fix.

@haberman
Copy link
Member

This is working as intended. float fields in protobuf are represented as IEEE 754 single precision numbers. This means they have less precision than PHP floats, which are generally IEEE 754 double precision numbers. So when you convert:

PHP float -> protobuf float -> PHP float

you lose precision.

Previously the protobuf PHP library was not properly clamping the precision. This made it inconsistent with the PECL C extension and inconsistent with other languages. Also the precision loss would happen anyway when serializing to binary format.

If this isn't the behavior you want, the best option is to switch your field from float to double. Unfortunately this is not a wire-compatible change.

@mattrx
Copy link
Author

mattrx commented Mar 10, 2021

Thank you, we will switch to double.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants