Precision and rounding fixes for money type
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: pgsql-hackers@postgreSQL.org
Date: 2017-05-19T19:53:35Z
Lists: pgsql-hackers
Attachments
- fix-money-precision-issues.patch (text/x-diff) patch
I looked a bit more carefully at cash.c in the wake of bug #14663, https://www.postgresql.org/message-id/20170519164653.29941.19098%40wrigleys.postgresql.org It seems to me that there are three different bugs in the multiplication and division operators: 1. As noted in the bug thread, applying rint() to the result of an integer division is useless, and it will cause precision loss if the 64-bit result exceeds 2^52 or thereabouts. We should drop it. 2. On the other hand, the cash-times-float operators really should apply rint() rather than allowing the default truncation behavior to happen when converting the float product to int64. 3. At least with my compiler (gcc 4.4.7), it seems that arithmetic between an int64 value and a float4 value is performed by casting the int64 to float4 and doing the arithmetic in float4. This results in really serious precision loss, since the result's only good to six digits or so. ISTM we'd be well advised to have the cash-and-float4 operators widen the float4 input to float8 and do the arithmetic in float8, so that they don't lose more precision than they have to. On modern machines there's unlikely to be any detectable speed difference. The attached patch rectifies these things and adds documentation about the truncation behavior of cash division. I propose to apply all of it to HEAD. What I'm less sure about is how much of it is a candidate to back-patch. I think point 1 (precision loss in what should be an exact integer operation) is a clear bug and we should back-patch it. But the other cases are not as open-and-shut; maybe we should just change those behaviors in HEAD. Thoughts? regards, tom lane
Commits
-
Fix precision and rounding issues in money multiplication and division.
- c101d83a3dd6 9.6.4 landed
- b3c536bce953 9.3.18 landed
- 83f4e8f71cdf 9.4.13 landed
- 798d2321eceb 9.2.22 landed
- 5032f704ee39 9.5.8 landed
- d761fe2182d9 10.0 landed