issue-#124 Range-check for SHORT(ENTIER(real))

The features that we decide to not apply in the current time
luowy
Posts: 234
Joined: Mon Oct 20, 2014 12:52 pm

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by luowy »

Ivan Denisov wrote:
luowy wrote:need free registers,DevCPC486.ConvMove
This is leading to redefining of many negative constants... and the Kernel compilation error.

I agree with Josef, that we can not change compiler in the release candidate stage.
correct it,DevCPC486.ConvMove

Code: Select all

			ELSE
				(*y.form := f;*)
				IF m = Stk THEN
					y.form := f;
					IF ((f < Int32) OR (f = Char16)) & (y.mode # Reg) THEN LoadW(y, hint, stop) END;
					Push(y)
				ELSIF m # Undef THEN
					y.form := f;
					IF f = Int64 THEN
						IF y.mode # Reg THEN LoadLong(y, hint, stop) END;
						Free(y); y.form := Int32; z := x; z.form := Int32; DevCPL486.GenMove(y, z);
						IF z.mode = Reg THEN ASSERT(z.reg # y.index); z.reg := z.index ELSE INC(z.offset, 4) END;
						y.reg := y.index; DevCPL486.GenMove(y, z);
					ELSE
						IF y.mode # Reg THEN LoadW(y, hint, stop) END;
						Free(y); DevCPL486.GenMove(y, x)
					END
				ELSIF (y.mode = Stk) & (y.form = Int64) & (f = Int32 )THEN  (*SHORT(ENTIER(real))*)
					LoadLong(y, hint, stop);
					y.form := f; z:=y; z.reg:=z.index; Free(z);
				ELSE
					 y.form := f
				END
			END
		END	
	END ConvMove;
I have tested the whole framework with Dev/Docu/Build-Tool.odc
Ivan Denisov
Posts: 1700
Joined: Tue Sep 17, 2013 12:21 am
Location: Russia

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by Ivan Denisov »

Ok.

That is the total changes suggested by LuoWy
http://redmine.blackboxframework.org/pr ... 3e1d01b11f

This is version for testing:
http://blackboxframework.org/unstable/i ... c1.630.zip
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by Robert »

Ivan Denisov wrote:That is the total changes suggested ...
It seems too early to discuss in great detail the implementation of proposed changes when we haven't agreed we want a change, or precisely what that change should do.

The arguments against:
1 - No need; no bug has been identified.
2 - Backward compatibility (actually I think this is a weak agrument!)
3 - Extra instructions may make existing code slower for no major advantage
4 - Risk; this is a serious change late in the development cycle.

The arguments for:

No one has made any clear arguments yet.

I do think there is a bit of an issue here, but the extended / improved documentation suggestions address that issue satisfactorily (in my opinion!).
cfbsoftware
Posts: 204
Joined: Wed Sep 18, 2013 10:06 pm
Contact:

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by cfbsoftware »

luowy wrote:it do not affect existing code at all, all existing code have already add explicit cumbersome range checking for no trap.
Of course it affects existing code or we wouldn't even be considering the issue. Robert's example is one where existing behaviour would be changed. It can't be classified as a bug if the behaviour is implementation-dependent and has not been unambiguously specified. I agree that all is required is more explicit documentation. Robert's document is a very good start.
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by Josef Templ »

I have updated the wording for the range checking slightly as proposed by Robert.
See the diff at http://redmine.blackboxframework.org/pr ... 657fa2fa71.

REAL underflow leads to zero. Tested and added.

IN clarified. Should be clear now.
Since there are two possible behaviours in case of s in memory (TRAP or random result)
I have kept that. This is important information.
(Such a TRAP can be generated easily if SYSTEM.VAL(LONGINT, y * 2) with y: INTEGER is compiled.
The second register is undefined and (in my experiments) happens to be very large. So a TRAP in the compiler results.)
@luowy: This would be a fix in the compiler worth to be attempted.

- Josef
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by Robert »

Concerning REAL arithmetic ...

I said that usually this was done to 80 bits. Josef changed this to all operations are 80 bits. I gave an explanation why "ASSERT(Math.Pi() = Math.Pi(), 45)" TRAPs.

I suspect these are all over simplifications. Does anyone know the true story? And it they do, is it so complicated that it is not appropriate to include it here?
[Josef - I prefer to keep the word usually; did you change it for a good reason?]

My guess is that when expressions reach a certain level of complexity it is not practical to keep all the intermediate results on the FPU stack, and some are flushed to memory using 64 bits, thus rounding the native 80 bit values.

If this is the case, it raises the question if it is practical or desirable to change this behaviour - ie use 80 bits in RAM for this temporary stack? From my perspective, and mathematical / engineering background, I prefer to keep the extra accuracy whenever practical.
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by Robert »

The examples I gave to illustrate REAL rounding are maybe the most surprising, but the example below illustrates the point about breaking compound expressions more directly and simply. Should we include both?

Code: Select all

 VAR
    a, b, c, x, y, z  :  REAL;
  BEGIN
    a  :=  1000000000000.;
    b  :=  3.;

    x  :=  a / b - 333333333333.;	(*  Correct to 7 digits  *)
    c  :=  a / b;
    y  :=  c - 333333333333.;	(*  Correct to 4 digits  *)
    z  :=   1000000000000. / 3. - 333333333333.;	(*  Correct to 4 digits  *)
The explanation of the last line is that constant expressions are evaluated at compile time using 64 bits for intermediate values; if the expression is of type SHORTREAL the final result is cast as required. A single CONST declaration can behave as both a REAL constant and a SHORTREAL constant.
Last edited by Robert on Tue Aug 23, 2016 9:31 am, edited 1 time in total.
luowy
Posts: 234
Joined: Mon Oct 20, 2014 12:52 pm

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by luowy »

Robert wrote:My guess is that when expressions reach a certain level of complexity it is not practical to keep all the intermediate results on the FPU stack, and some are flushed to memory using 64 bits, thus rounding the native 80 bit values.
yes,currently the compiler do this way.
Robert wrote:If this is the case, it raises the question if it is practical or desirable to change this behaviour - ie use 80 bits in RAM for this temporary stack? From my perspective, and mathematical / engineering background, I prefer to keep the extra accuracy whenever practical.
it can be implemented, we'd better discuss enough before.
what result dose the C compiler give us? I prefer C standard.
User avatar
Robert
Posts: 1024
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by Robert »

luowy wrote:what result dose the C compiler give us? I prefer C standard.
There is / has been more than 1 standard. This paper (Kahan is often described as the "Father of floating point", and was very influential in the current IEEE 754 standard implemented in modern FPUs) (partly) describes these C standards - see page 12 - , and explains why the modern ones are so damaging. Look for the quote below.

Additional accuracy always reduces risk, and when it is available for free (or very cheaply) using it is the preferred decision.

https://people.eecs.berkeley.edu/~wkahan/Triangle.pdf
By the mid 1980s the dismal politics of computer language standardization had undermined that reliability by allowing “ new ” semantics
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: issue-#124 Range-check for SHORT(ENTIER(real))

Post by Josef Templ »

Robert wrote:Concerning REAL arithmetic ...

I said that usually this was done to 80 bits. Josef changed this to all operations are 80 bits. I gave an explanation why "ASSERT(Math.Pi() = Math.Pi(), 45)" TRAPs.

I suspect these are all over simplifications. Does anyone know the true story? And it they do, is it so complicated that it is not appropriate to include it here?
[Josef - I prefer to keep the word usually; did you change it for a good reason?]

My guess is that when expressions reach a certain level of complexity it is not practical to keep all the intermediate results on the FPU stack, and some are flushed to memory using 64 bits, thus rounding the native 80 bit values.

If this is the case, it raises the question if it is practical or desirable to change this behaviour - ie use 80 bits in RAM for this temporary stack? From my perspective, and mathematical / engineering background, I prefer to keep the extra accuracy whenever practical.
There are 8 FPU registers and it is very hard to construct an expression that needs more.
In case of register stack overflow you get an error 216 (not enough floating-point registers: simplify expression).
The Intel FPU uses 80 bits internally and that's why all operations are internally done with 80 bits.
Function calls inside an expression flush the fpu stack to memory before the call.
This leads to 64 bit accuracy and should be added to the docu.

I will also add a note on the precision of constant expressions. Thanks for the hint.
The only problem is that this is not related to range checking at all, also the comparison examples.
Maybe we need another section: "Floating point accuracy" or similar.

Among numerical programmers it is generally agreed that floating point values should normally not
be compared for equality but some epsilon should used as a tolerance.

There is no need to change anything in the language or compiler.
As far as I know this is very much the same as in C.

- Josef
Post Reply