Thread

Commits

  1. Fix precision and rounding issues in money multiplication and division.

  1. Precision and rounding fixes for money type

    Tom Lane <tgl@sss.pgh.pa.us> — 2017-05-19T19:53:35Z

    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