Skip to content

Floats can lose precision when loading to BigQuery #326

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

Closed
danielchatfield opened this issue Sep 1, 2020 · 6 comments · Fixed by #336
Closed

Floats can lose precision when loading to BigQuery #326

danielchatfield opened this issue Sep 1, 2020 · 6 comments · Fixed by #336
Assignees
Labels
priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@danielchatfield
Copy link

danielchatfield commented Sep 1, 2020

The float precision is set here: https://github.com/pydata/pandas-gbq/blob/d251db03b159447331ac9ae63e13d295d75bad70/pandas_gbq/load.py#L22

This is insufficient to represent all 64 bit floats without losing precision. For example 26/59 should be represented as 0.4406779661016949 but under this it is represented as 0.440677966101695.

This was added intentionally here to fix a different issue but it causes us some issues as we need perfect reconciliation between systems. It seems like it should be possible to get the best of both worlds and output the correct number of digits in all cases.

The original suggestion was to use %g but this was changed to %.15g – it's not clear to me what the rationale is for that, it seems like %g is strictly better but I'm sure I'm missing something.

@danielchatfield
Copy link
Author

@max-sixty I was wondering if you might be able to provide some help / guidance here?

@dkapitan
Copy link

dkapitan commented Sep 7, 2020

@danielchatfield

Not sure if this is helpful, but I think one of the issues as explained here is that a conservative choice is made in the number of significant digits.

A possible solution if you do need to have larger precision is to use .parquet format instead, as suggested here?

@max-sixty
Copy link
Contributor

Thanks @dkapitan

@tswast
Copy link
Collaborator

tswast commented Oct 2, 2020

Would %.16g avoid the precision issues?

@tswast tswast added priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. labels Nov 6, 2020
@tswast
Copy link
Collaborator

tswast commented Nov 6, 2020

The original suggestion was to use %g but this was changed to %.15g – it's not clear to me what the rationale is for that, it seems like %g is strictly better but I'm sure I'm missing something.

According to https://docs.python.org/3.6/library/string.html#formatspec

A precision of 0 is treated as equivalent to a precision of 1. The default precision is 6.

I think that would result in too much rounding on some systems.

@tswast
Copy link
Collaborator

tswast commented Nov 6, 2020

According to https://en.wikipedia.org/wiki/IEEE_754#Character_representation 17 digits are precision are required to preserve the original binary value. 16 digits was not enough in my testing of #336

@tswast tswast self-assigned this Nov 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants