31.08.2021 23:53, Mark Rotteveel wrote:

The only debatable feature of dialect 3 division is the fact the calculation stops (equivalent to floor rounding), while reduction of scale through assignment or cast applies half-up rounding, on the other hand, this behaviour is consistent with integer division, otherwise NUMERIC(18,0) division and BIGINT division would have to behave differently (e.g. 14/3 = 5 for NUMERIC(18,0) vs = 4 for BIGINT), which would be confusing as hell, though technically you could solve that by applying the "The precision and scale of the result of division are implementation-defined." (there is no requirement that BIGINT/BIGINT is BIGINT or NUMERIC/DECIMAL with a scale of 0).

  Below is comment from code ArithmeticNode::divide2() at 
src\dsql\ExprNodes.cpp:

         * In the SQL standard, the precision and scale of the quotient of exact
         * numeric dividend and divisor are implementation-defined: we have 
defined
         * the precision as 18 (in other words, an SINT64), and the scale as the
         * sum of the scales of the two operands.  To make this work, we have to
         * multiply by pow(10, -2* (scale of divisor)).
...
         * To maximize the amount of information in the result, we scale up
         * the dividend as far as we can without causing overflow, then we 
perform
         * the division, then do any additional required scaling.

So, 127.13 / 3.4618 evaluates in a following way:

127.13 is NUMERIC(5, 2) with value 12713 and scale -2
3.4618 is NUMERIC(5, 4) with value 34618 and scale -4

12713 * 10^8 / 34618 = 36723669 (integer division, no rounding)

Result is NUMERIC(18, 6) with value 36723669 and scale -6, or 36.723669

Hope it helps,
Vlad


Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to