6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 4:51 am

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Mon Mar 06, 2017 11:23 pm 
Offline

Joined: Thu Sep 15, 2016 1:52 pm
Posts: 60
Location: UK
Hi,
I'm just following a tutorial from http://www.forth.com and typed in two words that together will calculate how long it would take an amount to double if the interest was 6%.
The word definitions are:
Code:
: R%  10 */  5 +  10 / ;
: DOUBLED
     6 1000 21 1 DO  CR ." YEAR " I 2 U.R
           2DUP R% +  DUP ."    BALANCE " . 
           DUP 2000 > IF  CR CR ." more than doubled in "
                             I . ." years " LEAVE
                    THEN
      LOOP 2DROP ;

So I tried this with gforth and got the following result:
Code:
$ gforth
Gforth 0.7.2, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
: R%  10 */  5 +  10 / ;  ok
: 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 2DROP ;  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

Pretty much what I expected, but when I tried the code with Tali forth I got some really unexpected results:
Code:
$ py65mon --mpu 65C02 -r ophis.bin
Reset with new MPU 65C02

        PC  AC XR YR SP NV-BDIZC
65C02: 0000 00 00 00 ff 00110000
Wrote +16384 bytes from $c000 to $ffff

        PC  AC XR YR SP NV-BDIZC
65C02: 0000 00 00 00 ff 00110000

Booting Kernel for the Uberquirrel Mark Zero
Scot W. Stevenson <scot.stevenson@gmail.com>
Kernel Version Alpha 004 (11. Feb 2015)

Tali Forth for the 65c02
Version BETA (31. Dec 2016)
Tali Forth comes with absolutely NO WARRANTY
Type 'bye' to exit

: R%  10 */  5 +  10 / ;   ok
: 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 in "  compiled
i . ." years " leave  compiled
then  compiled
loop 2drop ;  ok
doubled
year  1   balance 1060
year  2   balance -5429
year  3   balance 799
year  4   balance -5706
year  5   balance -6047
year  6   balance -6409
year  7   balance -240
year  8   balance 6299

more than doubled in in 8 years  ok

I know that Tali Forth has been shelved in favour of Liara Forth, but does this misbehaviour exists Liara Forth as well?


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 07, 2017 12:43 am 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
I'd take a hard look at the R% word and see if that's working right. Mind, I'm not saying your code is wrong, but I'm just guessing the problem is likely */, /, or +.

So, I'd do some primitive testing on those to make sure they're working right. I'd mostly suspect */ first.


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 07, 2017 10:39 am 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
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.


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 07, 2017 1:41 pm 
Offline

Joined: Thu Sep 15, 2016 1:52 pm
Posts: 60
Location: UK
Thanks Scotws!


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 07, 2017 6:13 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
scotws wrote:
it is based on FIG Forth code modified by Dr. Jefyll

Actually, credit for the original code goes to Bruce Clark (aka dclxvi), not FIG. My bad. I have updated my post to clarify this point and a few others.

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: