Search Postgresql Archives

Re: rounding problems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On May 12, 2008, at 6:37 PM, Justin wrote:
lets take this
   select (9/10), (9/10)::numeric, (9::numeric/10::numeric), (9./10),
(9*.1)

With the given select statement i expected the results all to be same, especially sense it cast 4 of the 5 to numeric either with explicit cast
or by containing a decimal.  Instead postgresql cast the  first 2
calculations to integer, it then uses integer math so the result is 0.

Putting a decimal on a string of digits is the standard way to specify that it's numeric rather than integer; see 4.1.2.4. Numeric Constants:

http://www.postgresql.org/docs/8.3/interactive/sql-syntax- lexical.html#AEN1276>

In other words, 9. is equivalent to 9::numeric, though the latter involves an operation on an integer.

If a calculation contains a numeric value, any integers involved will be cast to a numeric value first, and then the calculation will proceed numerically.

9/10 => 0 (a purely integer calculation, division truncates the fractional part) (9/10)::numeric => 0::numeric => 0. (using parentheses forces the integer calculation to occur *before* the cast) 9::numeric/10::numeric => 9./10. => 0.9 (using one or two casts forces a numeric calculation) 9./10 => 9./10. => 0.9 (specifying a numeric value forces the integer to be cast to numeric)

To Add further conversion to my small brain there is a specific type
cast to the second calculation but it still returned 0.  Not what i
would have expected. After thinking about it for say 10 seconds, i see
that Postgresql is following the order of operation in the 2nd
calculation where it does integer math then cast the results to numeric.

I made the incorrect assumption Postgresql would have casted all the
arguments to numeric then done the math.

Not when you change the order of evaluation by using parentheses. See the precedence table in 4.1.6. Lexical Precedence:

http://www.postgresql.org/docs/8.3/interactive/sql-syntax- lexical.html#SQL-PRECEDENCE

After thinking this through
for a short bit i see why postgresql is casting the arguments to integer
type as numeric/floating point math can be a pretty heavy hit
performance wise.

So this prompts the question how does postgresql decide what types to
cast arguments to.

It starts with operator precedence to determine the order of operation, and then for each operator it decides how it will cast arguments for the "best" results.

-- Andy



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux