[Aldor-l] The smallest machine integer is "-"
Christian Aistleitner
tmgisi at gmx.at
Mon Mar 5 05:16:04 EST 2007
Hello Ralf,
On Sun, 04 Mar 2007 16:06:58 +0100, Ralf Hemmecke <ralf at hemmecke.de> wrote:
> The smallest machine integer is printed as "-".
I think I reported something like that years ago, sadly enough I cannot
find the bug report.
However, as the aldor.org people are stepping forward with a new release,
let me support them with the bug fix I wrote back then.
For 32bit machines min$MachineInteger is -2147483648 while
max$MachineInteger is 2147483647. That's what can be expected from the way
integers are typically represented within computers, so that's ok.
However, << of MachineInteger comes down to print$IntegerTypeTools. There,
the treatment of negative numbers goes as follows
if x < 0 then {
p := p << minus;
x := -x;
}
After the if statement, x should hold the absolute value af x's original
value. However, if x is min$MachineInteger before the if statement, x is
still min$MachineInteger after the if statement, because of an overflow.
This overflow is inherent to the format used for number specification.
The implicit assumption that x is positive after the if statement fails.
I propose to perform one division step before negating x. Then -x <
max$MachineInteger and it can be savely inverted. I shifted the
declaration of l and introduced one anticipatory division step. Finally, I
added an assert. This converts print$IntegerTypeTools to the following
function:
print(x:T, base:T, p:TextWriter):TextWriter == {
macro REC == Record(digit:Character, next:Pointer);
import from Boolean, Character, REC;
zero? x => p << char 48;
l:REC := nil;
if x < 0 then {
p := p << minus;
-- this brought forward division step
-- compensates for
-- -min$MachineInteger > max$MachineInteger
(x, r) := divide(x, base);
l := [digit (-r), l pretend Pointer];
x := -x;
}
assert( x > 0 );
while x > 0 repeat {
(x, r) := divide(x, base);
l := [digit r, l pretend Pointer];
}
while ~nil? l repeat {
p := p << l.digit;
l := l.next pretend REC;
}
p;
}
For those, who need a quick fix can use Aldor's extend functionality. But
you have to be careful not to call <<$MachineInteger from the file you
extended it in. The attached part1.as implements the workaround. Due to
Aldor's extend, you have to use the overridden <<$MachineInteger from
another file, i.e.:part2.as.
Calling via
aldor -Fao -Fo -laldor part1.as && \
ar r libpart1.al part1.ao && \
ar r libpart1.a part1.o && \
aldor -Fx -lpart1 -laldor part2.as && \
./part2
gives
cc1: note: -fwritable-strings is deprecated; see documentation for details
cc1: note: -fwritable-strings is deprecated; see documentation for details
cc1: note: -fwritable-strings is deprecated; see documentation for details
-2147483648
0
1
2147483647
and demonstrates the working workaround.
Kind regards,
Christian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: part1.as
Type: application/octet-stream
Size: 1192 bytes
Desc: not available
URL: <http://mail.aldor.org/pipermail/aldor-l_aldor.org/attachments/20070305/2e784848/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: part2.as
Type: application/octet-stream
Size: 281 bytes
Desc: not available
URL: <http://mail.aldor.org/pipermail/aldor-l_aldor.org/attachments/20070305/2e784848/attachment-0003.obj>
More information about the Aldor-l
mailing list