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