Thanks for pointing this out -
jgroth wrote:
I know that Tali Forth has been shelved in favour of Liara Forth, but does this misbehaviour exists Liara Forth as well?
Liara can't do
DO/LOOP yet (that, native compiling and the backwards-compatible words
WORD and
FIND are what's still missing), but we can test
R%. For those following this, the example is from
https://www.forth.com/starting-forth/5- ... rithmetic/ where
R% is "rounded-percent":
Code:
: r% ( n % -- n ) 10 */ 5 + 10 / ;
The definitely correct example from the book is
Code:
227 32 R% .
for 73, which Liara does fine, and Tali responds to with -6480. Oops.
Breaking down the words, we get to
M*, which works fine for for small values, but pukes at larger ones:
Code:
1000 100 m* d>s . -31072 ok
This leads us to
UM*, which shows the same behavior, which is strange, because it is based on FIG Forth code modified by Dr. Jefyll at
viewtopic.php?f=9&t=689 and is therefore correct
ex cathedra. But watch this:
Code:
( Gforth ) decimal 1000 100 um* hex swap u. u. 186A0 0 ok
( Liara ) decimal 1000 100 um* hex swap u. u. 86a0 1 ok \ numbers lowercase known behavior
( Tali ) decimal 1000 100 um* hex swap u. u. 86A0 1 ok
Tali and Forth have 16-bit cells, and so the highest digit ("1") gets pushed into the higher cell. Gforth has 64-bit cells (see output of
1 cells 8 * . for cell size in bits) and so each cell can handle
seriously larger numbers than poor Tali and Liara. So that's one problem,
*/MOD and therefore
*/ produce single-cell results by simply dropping off the top cell. Gforth doesn't care, because it still has $186A0, while Tali and Liara are stuck with $86A0, which is a totally different number, and negative to boot. I'll put this example in the documentation as a known issue.
However - this still doesn't explain why Tali and Liara are producing different numbers for
R%. Walking through the defintion with
.S after every step, we find that Tali thinks 731 / 10 is -6480 ( Liara says 73). Both are based on the same word:
Code:
: / >r s>d r> sm/rem swap drop ;
To cut a long story short, it turns out that Tali in fact does have a bug, but not in the complicated math stuff, which I actually tested with
http://www.forth200x.org/documents/html ... #usage:div for both versions, but in
S>D, line 5366, where it checks the sign of the LSB for expansion, not the MSB. Liara as a 16-bit machine can't make that error. Now re-running the example with corrected
S>D:
Code:
: doubled compiled
6 1000 21 1 do cr ." year " i 2 u.r compiled
2dup r% + dup ." balance " . compiled
dup 2000 > if cr cr ." more than doubled in " compiled
i . ." years" leave compiled
then compiled
loop 2 drop ; ok
doubled
year 1 balance 1060
year 2 balance 1124
year 3 balance 1191
year 4 balance 1262
year 5 balance 1338
year 6 balance 1418
year 7 balance 1503
year 8 balance 1593
year 9 balance 1689
year 10 balance 1790
year 11 balance 1897
year 12 balance 2011
more than doubled in 12 years ok
Which is what Gforth gave us. Can't test it with Liara yet, but looks better.
Thanks again, corrected code pushed to GitHub.