[M3devel] opacity of Target.Int, overflow of Target.Int
Jay K
jay.krell at cornell.edu
Sun Feb 21 14:33:40 CET 2010
I *suspect* the "real" "big" problem is that left and right shift and "plain" shift should take a size.
- Jay
From: jay.krell at cornell.edu
To: hosking at cs.purdue.edu; m3devel at elegosoft.com
Subject: opacity of Target.Int, overflow of Target.Int
Date: Sun, 21 Feb 2010 10:31:06 +0000
1) Tony, I claim that if Target.Int is really opaque, then values of it should only be formed in Target.i3/Target.m3.
Or TInt/TWord/.i3/.m3, since they know deeply about it.
Having m3back know about them seems a bit off.
Granted, pushing constants that only m3back uses into Target/TInt/TWord isn't great either, pollutes them some.
This is a minor dilemna though.
2) Are you sure having a fixed precision of 8 bytes is correct here?
More generally are you sure TInt has the right interface?
How does one check for overflow within the precision one cares about?
I think I know.
I think Chop should return a boolean, as to if the value fits.
For that matter, have SignedChop and UnsignedChop.
Or TInt.Chop and TWord.Chop.
TInt.Chop is already SignedChop.
Do the math in 64bits, if that overflows, then overflow.
And then truncate to whatever, and that can overflow too.
This is related to "you all have convinced me that overflow isn't
all that important really, but range checking is".
So you in sense defer the overflow. You don't do the complete
overflow check at Add or whatever, but then you do a range
check converting to a small size.
But hm. This will skip "intermediate overflow". Does that matter?
1 billion * 8 / 8
Should that overflow in 32bits?
Well, easy enough, do the chop after each operation.
I said "defer", but it is brief.
1B * 8 / 8
isn't written as
1* 8 / 8
convert to 32bits
but rather
1B * 8
convert to 32bits
=> failure here
/ 8
convert to 32bits
?
3) Related to #2.
Where should RightShift insert zeros?
I guess you chop first, and then it works.
Proposed something like:
TInt:
PROCEDURE Chop (VAR r: Int; n: CARDINAL): BOOLEAN =
VAR extension := Mask * ORD(And (r [n-1], SignMask) = 0);
result := TRUE;
BEGIN
FOR i := n TO LAST(Int) DO
result := (result AND (r[i] # extension));
r[i] := extension;
END;
return result;
END Chop;
TWord:
PROCEDURE Chop (VAR r: Int; n: CARDINAL): BOOLEAN =
CONST extension = 0;
VAR result := TRUE;
BEGIN
FOR i := n TO LAST(Int) DO
result := (result AND (r[i] # extension));
r[i] := extension;
END;
return result;
END Chop;
But I have to back to your version of m3back and try these out.
Very speculative at the moment.
Could also leave the data alone upon failure, trivially related to previous:
TInt:
PROCEDURE Chop (VAR r: Int; n: CARDINAL): BOOLEAN =
VAR extension := Mask * ORD(And (r [n-1], SignMask) = 0);
BEGIN
FOR i := n TO LAST(Int) DO
IF r[i] # extension THEN
RETURN FALSE;
END;
END;
FOR i := n TO LAST(Int) DO
r[i] := extension;
END;
RETURN TRUE;
END Chop;
TWord:
PROCEDURE Chop (VAR r: Int; n: CARDINAL): BOOLEAN =
VAR result := TRUE;
BEGIN
FOR i := n TO LAST(Int) DO
IF r[i] # 0 THEN
RETURN FALSE;
END;
END;
FOR i := n TO LAST(Int) DO
r[i] := 0;
END;
return TRUE;
END Chop;
I'm not sure I like the subtlety of TInt.Chop vs. TWord.Chop.
I'd prefer TInt.UnsignedChop and TInt.SignedChop.
Granted, "Un" doesn't exactly stand out, but at least "signed" does and makes you wonder about and discover the existance of signed vs. unsigned.
Alternatively Chop and UChop. More subtle, but I think plenty programmars are used to the names "uchar", "ushort", "uint", "ulong". "u" is pretty widely recognized as meaning "unsigned". More so I believe than "Word".
(I still don't like the name "interface Long"!, it doesn't imply unsigned at all!)
- Jay
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20100221/72e2693b/attachment-0002.html>
More information about the M3devel
mailing list