On 31-08-2021 16:19, Molnár Attila wrote:
127.13 / 3.4618 = 36,72366976717315

It isn't, taken literally in dialect 3, the result is 36,723669 ;).

EXECUTE BLOCK
RETURNS (
   c0 NUMERIC(15,10),
   c1 NUMERIC(15,10),
   c2 NUMERIC(15,6),
   c3 NUMERIC(15,5),
   c4 NUMERIC(15,4))
AS
DECLARE VARIABLE a NUMERIC(15,2);
DECLARE VARIABLE b NUMERIC(15,4);
BEGIN
   a = 127.13;
   b = 3.4618;
   c0 = a / CAST(b AS DOUBLE PRECISION);--36,7236697672, this is OK
   c1 = a / b;--36,7236690000, this shoud be 36,7236700000
   c2 = a / b;--36,723669, this shoud be 36,723670
   c3 = a / b;--36,72367, this is OK
   c4 = a / b;--36,7237, this is OK
   SUSPEND;
END

If return variable scale is bigger or equal than operation result scale, then computed value is truncated, but when return variable scale is smaller than operation result scale then computed value is rounded. I think in all case value should be rounded, this behaviour is inconsistent, and also truncation is unexpected behaviour.

I opened a GitHub issue , but was closed : https://github.com/FirebirdSQL/firebird/issues/6928 <https://github.com/FirebirdSQL/firebird/issues/6928>
Mark suggested to start a conversation here.

I didn't suggest you start a discussion about this behaviour, I suggested you start a discussion about your wish that dialect 1 would not be dropped ("If you want to discuss retention of dialect 1, then please take that to firebird-devel.").

This has been the behaviour of NUMERIC/DECIMAL division in dialect 3 since InterBase 6.0. Changing that behaviour now would break or invalidate all applications that have been built with dialect 3 semantics of NUMERIC/DECIMAL division in mind.

It complies with the SQL standard. Though to be honest, that is a pretty low bar, as the specification doesn't specify much for NUMERIC/DECIMAL division other than that precision and rounding is implementation specific ("iv) The precision and scale of the result of division are implementation-defined." - SQL:2016-2, 6.29 <numeric value expression>)

#1 : This behaviour should be documented, I found nothing regarding this, and this result is unexpected. Calculation do not happens in double precision, and calculation stops when result scale is reached.

The result is unexpected *to you* and does not match what you've been relying on in dialect 1. Yes, it is not explicitly documented other than the resulting precision, but neither is the behaviour of division in dialect 1 other than that it results in a DOUBLE PRECISION. You can think of NUMERIC/DECIMAL division in dialect 3 as a form of integer division like in most programming language. That also stops when the final digit has been calculated. For example, 14/3 = 4, not 5, 14.0/3 = 4.6, not 4.7, 14.0/3.0 = 4.66, not 4.67, etc, in dialect 1, all those calculations produce 4.666666666666667. For dialect 3, you can think of 14.0/3.0 as doing 14000/30 and then shifting the decimal by two positions (14000/30 = 466, shift decimal by 2 = 4.66).

You haven't brought forth any real arguments why 21+ years of dialect 3 behaviour should be thrown out the window, other than that you don't like it because it isn't the same as in dialect 1.

I understand this is a bitter pill, but this difference is likely the reason why you've been using dialect 1 all this time.

#2 : Calculation method should be cofigurable
#2/A: possible configuration modes

-default: current mode

-double precision: operands converted to double, calculations happens in double, then result rounded and converted back to result type

If you want such behaviour, then you need to either stay on dialect 1, or cast one of the operands explicitly to double precision.

Mark
--
Mark Rotteveel


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

Reply via email to