Krishna Myneni
2024-03-22 13:59:24 UTC
For typical implementations of 2! and 2@, the storage of double length
numbers in memory do not correspond to the native byte ordering for a
double length number. For these implementations, the high order bits of
the double number are on the top cell of the stack, which is at a lower
memory address. For example,
2variable x
5 s>d .s
0
5
ok
x 2!
x 8 dump \ on a 32-bit little-endian system
A0AE7C0 : 00 00 00 00 05 00 00 00 ok
In the Forth 2012 standard, and in prior standards, the representation
of double numbers on the stack seems to be allowed to be implementation
defined. Thus, on a 32-bit system, the stack order of a 64 bit double
number, the standard does not specify whether the high 32 bits of the
number are on top of the stack or the low 32 bits. Hence, we have the
rationale (A.8.6.1.1140) for the word D>S to abstract the conversion of
a double to single length number (instead of using DROP).
To overcome this issue, we could simply decide that double length
numbers on the stack have a specific ordering corresponding to their
native memory ordering on the system, but this appears to be contrary to
some existing implementations, and it may also break code.
A better way to do this is to explicitly define D! and D@, so that the
native memory storage order is consistent for this type.
For little-endian Forth systems which place the high order cell of the
double number on top of the stack, the definitions would be
: D! ( d a -- ) >r swap r> 2! ;
: D@ ( a -- d ) 2@ swap ;
=== Example ===
5 s>d x d!
ok
x 8 dump
A0AE7C0 : 05 00 00 00 00 00 00 00 ok
x d@ .s
0
5
ok
=== End Example ===
More generally, the problem with the double number word set is that it
attempts to use the same word set for two different types:
1) pairs of cell length numbers
2) double length integers
It would be better to separate the words for these two types, the latter
having prefix of "D" and the former having prefix "2".
--
Krishna Myneni
numbers in memory do not correspond to the native byte ordering for a
double length number. For these implementations, the high order bits of
the double number are on the top cell of the stack, which is at a lower
memory address. For example,
2variable x
5 s>d .s
0
5
ok
x 2!
x 8 dump \ on a 32-bit little-endian system
A0AE7C0 : 00 00 00 00 05 00 00 00 ok
In the Forth 2012 standard, and in prior standards, the representation
of double numbers on the stack seems to be allowed to be implementation
defined. Thus, on a 32-bit system, the stack order of a 64 bit double
number, the standard does not specify whether the high 32 bits of the
number are on top of the stack or the low 32 bits. Hence, we have the
rationale (A.8.6.1.1140) for the word D>S to abstract the conversion of
a double to single length number (instead of using DROP).
To overcome this issue, we could simply decide that double length
numbers on the stack have a specific ordering corresponding to their
native memory ordering on the system, but this appears to be contrary to
some existing implementations, and it may also break code.
A better way to do this is to explicitly define D! and D@, so that the
native memory storage order is consistent for this type.
For little-endian Forth systems which place the high order cell of the
double number on top of the stack, the definitions would be
: D! ( d a -- ) >r swap r> 2! ;
: D@ ( a -- d ) 2@ swap ;
=== Example ===
5 s>d x d!
ok
x 8 dump
A0AE7C0 : 05 00 00 00 00 00 00 00 ok
x d@ .s
0
5
ok
=== End Example ===
More generally, the problem with the double number word set is that it
attempts to use the same word set for two different types:
1) pairs of cell length numbers
2) double length integers
It would be better to separate the words for these two types, the latter
having prefix of "D" and the former having prefix "2".
--
Krishna Myneni