Heater
Posts: 12623
Joined: Tue Jul 17, 2012 3:02 pm

Re: Introduction to BBC BASIC

Mon May 20, 2019 8:50 pm

Cool.

I stopped at unsigned add, sub, mul with my C++ version as well. Just enough to get the fibo done. No point in doing more when GMP is available.

User avatar
ScriptBasic
Posts: 1231
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Introduction to BBC BASIC

Mon May 20, 2019 9:36 pm

Sorry to hear that Richard. My approach with GMP is a secondary extension module. ALL extensions are optional with ScriptBasic. In reality only scriba is needed to run code.

Maybe your time would be better spent creating an extension module API?

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Tue May 21, 2019 6:57 am

ScriptBasic wrote:
Mon May 20, 2019 9:36 pm
Maybe your time would be better spent creating an extension module API?
There's no need. As I said, there's no technical problem in creating a BBC BASIC for SDL 2.0 library based on GMP - it's no different in principle from the existing BigInt library for BBC BASIC for Windows (which happens to be based on MAPM). It doesn't require any 'extension' to BBC BASIC itself, just the existing INSTALL statement.

The attractions of a library coded in 100% BBC BASIC are as a demonstrator of what can be achieved - and what I've got so far runs very nicely for more typical applications than a million-digit Fibonacci number! - and to avoid the need to package or link to GMP in the cross-platform distributions.

jahboater
Posts: 4424
Joined: Wed Feb 04, 2015 6:38 pm

Re: Introduction to BBC BASIC

Tue May 21, 2019 7:25 am

RichardRussell wrote:
Tue May 21, 2019 6:57 am
The attractions of a library coded in 100% BBC BASIC are as a demonstrator of what can be achieved - and what I've got so far runs very nicely for more typical applications than a million-digit Fibonacci number! - and to avoid the need to package or link to GMP in the cross-platform distributions.
Impressive! Reducing the number of dependencies is good, I wish more software did that.

But GMP and MPFR offer a lot more than basic arithmetic.

MPFR offers arbitrary precision floating point (with IEEE semantics) and a large collection of well documented math library functions.
https://www.mpfr.org/mpfr-current/mpfr. ... -Interface
https://www.mpfr.org/mpfr-current/mpfr. ... -Functions
That would be quite a bonus for BBC BASIC to offer, I doubt any other version of BASIC can do anything close.

And for example GMP has a Fibonacci function, that I suspect is much much faster and smaller than one created using individual arithmetic functions, and of course easier for the user.

There is also MPC for complex numbers.

:) Long long ago I was using a Sinclair ZX80 (BASIC) which didn't have floating-point. For fun, I tried to implement some limited floating-point math on it, but found that it took the entire memory of the machine just to implement simple addition :)

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Tue May 21, 2019 8:49 am

jahboater wrote:
Tue May 21, 2019 7:25 am
But GMP and MPFR offer a lot more than basic arithmetic.
Indeed, as does MAPM (which is what the BB4W library uses).although I think it's no longer supported. I don't know that I would fancy trying to write a comparable library in BBC BASIC code however!
I tried to implement some limited floating-point math on it, but found that it took the entire memory of the machine just to implement simple addition :)
I'm a little surprised. For BBC BASIC (Z80) I wrote the floating-point code entirely from scratch, even 'bootstrapping' the transcendental functions by using what I'd already written (FP add, subtract, multiply, divide) to optimise the coefficients of the power-series expansions. I thought that was rather neat! But I don't remember the code being very large: everything was done in CPU registers, not memory, because the Z80 had a good architecture for the 40-bit float format (32-bit mantissa, 8-bit exponent) used by BBC BASIC in those days. I held one FP argument in HLH'L'C and another in DED'E'B which left B'C' and A (and A') to hold, for example, a temporary extension to the mantissa and an operator. It was a tight fit, but it worked really nicely.

jahboater
Posts: 4424
Joined: Wed Feb 04, 2015 6:38 pm

Re: Introduction to BBC BASIC

Tue May 21, 2019 8:57 am

RichardRussell wrote:
Tue May 21, 2019 8:49 am
I'm a little surprised. For BBC BASIC (Z80) I wrote the floating-point code entirely from scratch, even 'bootstrapping' the transcendental functions by using what I'd already written (FP add, subtract, multiply, divide) to optimise the coefficients of the power-series expansions.
I wrote it in BASIC and the Sinclair ZX80 only had 1k of ram! It was so long ago (very early 80's) I cant remember what dialect of BASIC it was, except that it was nowhere near as capable as the later BBC BASIC.

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Tue May 21, 2019 4:14 pm

jahboater wrote:
Tue May 21, 2019 8:57 am
I wrote it in BASIC and the Sinclair ZX80 only had 1k of ram!
Tokenised BASIC was probably the best way to use that limited resource, but in a couple of respects it's not ideal for writing floating-point code. Firstly I suspect Sinclair BASIC's integers were only 16 bits (unlike BBC BASIC's 32-bits) and - more importantly - BASIC gives you no direct access to the CPU's carry and overflow flags which are so crucial in the efficient implementation of FP arithmetic.

That remains highly relevant today, because the lack of access to carry and overflow is forcing me to store no more than 62 bits in each 64 bit 'limb' so that I can detect those conditions by looking at the two remaining bits in BASIC.

Heater
Posts: 12623
Joined: Tue Jul 17, 2012 3:02 pm

Re: Introduction to BBC BASIC

Fri May 24, 2019 3:54 pm

Richard,

Continuing from the discussion of first class functions in the ScriptBasic thread:
The principal aspect is creating a new function from scratch at run time, not so much the pointer passing.
Impressive.
Do you mean creating a composite function incorporating one of the built-in functions?
Sounds like you have it covered. I was thinking of a function that manufactures new code for a new function and returns it, rather than composing things with pointers to existing functions like the C example does on the Rosetta page.

An example in Scheme says what I mean:

Code: Select all

; Makes a binary operator from a string and returns a function that applies it to two parameters. 
(define binaryExpr (lambda (s)
  (define oper (eval (string->symbol s)))
  (lambda (x y)
    (oper x y)
  )
))

(define plus
  (binaryExpr "+")
)

(display (plus 3 2))
(newline)
I know nothing much of Scheme so that is probably a terrible example.

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Fri May 24, 2019 4:57 pm

Heater wrote:
Fri May 24, 2019 3:54 pm
I was thinking of a function that manufactures new code for a new function and returns it, rather than composing things with pointers to existing functions like the C example does on the Rosetta page.
My BBC BASIC solution to the Rosetta Code task implements FNcompose() by taking two function pointers and creating a function which calls one followed by the other. That only works with user-defined functions because they are the only ones that have function pointers as such (so to satisfy the requirement that "at least one function should be built in" I have wrapped them in user-defined functions).

The more general solution would involve passing not function pointers to FNcompose() but actual code, in the form of a string. That's perfectly possible, but the code would be more complex. This is the sort of trick you can really only play with an interpreted language, because you know all the resources necessary to run the code are available (i.e. the interpreter itself). With a compiled language you can't be certain that the compiler will be available on the target machine.

ejolson
Posts: 3028
Joined: Tue Mar 18, 2014 11:47 am

Re: Introduction to BBC BASIC

Fri May 24, 2019 5:01 pm

Heater wrote:
Fri May 24, 2019 3:54 pm
Richard,

Continuing from the discussion of first class functions in the ScriptBasic thread:
The principal aspect is creating a new function from scratch at run time, not so much the pointer passing.
Impressive.
Do you mean creating a composite function incorporating one of the built-in functions?
Sounds like you have it covered. I was thinking of a function that manufactures new code for a new function and returns it, rather than composing things with pointers to existing functions like the C example does on the Rosetta page.

An example in Scheme says what I mean:

Code: Select all

; Makes a binary operator from a string and returns a function that applies it to two parameters. 
(define binaryExpr (lambda (s)
  (define oper (eval (string->symbol s)))
  (lambda (x y)
    (oper x y)
  )
))

(define plus
  (binaryExpr "+")
)

(display (plus 3 2))
(newline)
I know nothing much of Scheme so that is probably a terrible example.
Since there is no runtime input, there is nothing that needs to be changed at runtime, so what's the point of the lambda? While correct, I find it about as practical as using object oriented programming to represent zoo animals.

In my opinion a more reasonable task would be to accept user input (an algebraic expression in x) that represents a function f(x) and then lambda up a new function df(x) that computes the derivative of that function.

Heater
Posts: 12623
Joined: Tue Jul 17, 2012 3:02 pm

Re: Introduction to BBC BASIC

Fri May 24, 2019 5:08 pm

I think you are right. A compiled language program could do it, possibly, if it carried the compiler around with itself!

At some point it's not worth the hassle and one might as well use an interpreter.

I guessed you had wrapped the builtins with user defined functions because you can't get pointers to builtins. That sounds fine to me.

I was not thinking as far ahead as composing functions. Only creating and returning one that did not exist in the original source. Perhaps from a string, or whatever. Think an expression parser that turns an input string into a function that becomes part of the program.

That is out of scope for most languages never mind the BASICs.

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Fri May 24, 2019 5:19 pm

Heater wrote:
Fri May 24, 2019 5:08 pm
That is out of scope for most languages never mind the BASICs.
It's one of the things we have Acorn to thank for, because when they designed BBC BASIC, back in 1981, they created a hybrid of the Microsoft-style BASIC that the BBC had asked for (albeit extended to support structured programming) and their existing Atom BASIC which had the necessary low-level indirection operators to manipulate memory - including the program itself. So BBC BASIC is unusual in supporting self-modifying code and run-time function creation, albeit that the penalty you pay is a greatly increased likelihood of a catastrophic crash if you misuse those features!

Heater
Posts: 12623
Joined: Tue Jul 17, 2012 3:02 pm

Re: Introduction to BBC BASIC

Fri May 24, 2019 5:24 pm

ejolson,
Since there is no runtime input, there is nothing that needs to be changed at runtime, so what's the point of the lambda?
That is quite right, no point at all, not for my noddy example above.
In my opinion a more reasonable task would be to accept user input (an algebraic expression in x) that represents a function f(x) and then lambda up a new function df(x) that computes the derivative of that function.
Yes indeed.

Thing is, the example shows a way to turn a string into a Scheme operator. With a little imagination one starts to see how that can be used to turn a string input by the user into a Scheme operator. By the way, the "operator" in the example need not be a simple "+". "-" etc. It could be a complex piece of Scheme code in a string.

With a bit more imagination it shows how it's possible to build functions that evaluate complex expressions that are input as strings.

This is all a bit more than an interpreter of the input expression strings as one might create in C. It "compiles" the input expressions into Scheme functions.

I'm working on it....

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Fri May 24, 2019 5:53 pm

Heater wrote:
Fri May 24, 2019 5:24 pm
With a bit more imagination it shows how it's possible to build functions that evaluate complex expressions that are input as strings.
Many interpreted BASICs (BBC BASIC and Liberty BASIC among them) include an EVAL function so that "evaluating complex expressions input as strings" becomes trivial:

Code: Select all

      REPEAT
        INPUT LINE "Enter a numeric or string expression: " expression$
        ON ERROR LOCAL IF FALSE THEN
          REM 'Try' clause:
          PRINT EVAL(expression$)
        ELSE
          REM 'Catch' clause:
          PRINT REPORT$
        ENDIF : RESTORE ERROR
      UNTIL FALSE
      END
The expression can be as complex as you like and can contain both built-in and user-defined functions. The strange 'ON ERROR' construction is BBC BASIC's implementation of Structured Exception Handling (SEH) and avoids the need of a line number or label as would be necessary in the traditional ON ERROR GOTO statement.

Heater
Posts: 12623
Joined: Tue Jul 17, 2012 3:02 pm

Re: Introduction to BBC BASIC

Fri May 24, 2019 6:29 pm

That is cool.

I guess it's restricted to only evaluating strings that contain valid BBC BASIC and returning the result. Not being able to create BBC BASIC functions from the string that can be called later. Or the interpretation of some other syntax in the string. Not that I would expect that.

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Fri May 24, 2019 6:42 pm

Heater wrote:
Fri May 24, 2019 6:29 pm
Not being able to create BBC BASIC functions from the string that can be called later.
Correct. To achieve that needs an adaptation of the technique used in the Rosetta Code solution. Not particularly difficult, but not as straightforward as EVAL.

jalih
Posts: 60
Joined: Mon Apr 15, 2019 3:54 pm

Re: Introduction to BBC BASIC

Fri May 24, 2019 7:24 pm

Heater wrote:
Fri May 24, 2019 5:08 pm
Only creating and returning one that did not exist in the original source. Perhaps from a string, or whatever. Think an expression parser that turns an input string into a function that becomes part of the program.

That is out of scope for most languages never mind the BASICs.
Not the way that I would write it, but 8th can do:

Code: Select all

: plus  \ x y -- x+y
  "+" eval ;


3 2 plus . cr
"Hello " "world!" plus . cr
or just:

Code: Select all

"plus" (:) "+" eval ;
3 2 plus . cr
"Hello " "world!" plus . cr
Result is:

Code: Select all

5
Hello world!

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Mon May 27, 2019 2:38 pm

RichardRussell wrote:
Mon May 20, 2019 8:29 pm
I'll play a bit more, but if I can't improve the performance to at least match the classic BASIC solution I probably won't pursue it any further.
Progress! I've now got my 'native' (BBC BASIC) BigInt library to evaluate the million-digit Fibonacci number faster than the 'classic BASIC' version: 7 minutes compared with 12 minutes on the same (fairly fast) PC. Not a dramatic improvement, admittedly, but I'm reasonably satisfied because the library is general purpose rather than being in any way optimised for the Fibonacci challenge.

This is the program:

Code: Select all

      HIMEM = PAGE + 20000000
      INSTALL @lib$ + "bigint"
      PROCbiginit

      f0%% = FNbignew(1000000)
      f1%% = FNbignew(1000000)

      TIME = 0
      PROCfibonacci(4784969, f0%%, f1%%)
      *spool fibo1M.txt
      PRINT FNbigstr(f0%%)
      *spool
      PRINT TIME/100 " seconds"
      END

      REM Fibonacci calculation using the doubling algorithm:
      DEF PROCfibonacci(N%, f%%, g%%)
      LOCAL S%, a%%, b%%, c%%, d%%
      S% = N% * LOG((SQR(5) + 1) / 2) + 1
      IF N% = 0 THEN
        a%% = FNbignew(1)
        b%% = FNbignew(1)
        PROCbigval(b%%, "1")
        PROCbigcpy(a%%, f%%) : REM f = 0
        PROCbigcpy(b%%, g%%) : REM g = 1
        ENDPROC
      ENDIF
      a%% = FNbignew(S%) : b%% = FNbignew(S%)
      PROCfibonacci(N% DIV 2, a%%, b%%)
      c%% = FNbignew(S%) : d%% = FNbignew(S%)

      PROCbiguadd(b%%, b%%, c%%)
      PROCbigusub(c%%, a%%, d%%)
      PROCbigumul(d%%, a%%, c%%)   : REM c = a * (b * 2 - a)
      PROCbigumul(a%%, a%%, d%%)
      PROCbigumul(b%%, b%%, a%%)
      PROCbiguadd(d%%, a%%, b%%)   : REM b = a * a + b * b
      IF N% AND 1 THEN
        PROCbigcpy(b%%, f%%)       : REM f = b
        PROCbiguadd(b%%, c%%, g%%) : REM g = b + c
      ELSE
        PROCbigcpy(c%%, f%%)       : REM f = c
        PROCbigcpy(b%%, g%%)       : REM g = b
      ENDIF
      ENDPROC
The library uses 64-bit pointers/handles to represent the big integers. I've tried to leverage 'unique' features of BBC BASIC as far as possible, so internally it makes extensive use of whole-array operations and indirection. For example adding two bigints together is done with the following code (carries between limbs are dealt with separately):

Code: Select all

      c%%() = a%%() + b%%()
This allows loops to be eliminated to a large extent: there is only one FOR...NEXT loop in the entire library! I'm still not sure whether to put in the extra effort to extend the library to cope with signed numbers and other operations such as division; I might set that as a challenge for the BBC BASIC community.

ejolson
Posts: 3028
Joined: Tue Mar 18, 2014 11:47 am

Re: Introduction to BBC BASIC

Mon May 27, 2019 6:38 pm

RichardRussell wrote:
Mon May 27, 2019 2:38 pm
RichardRussell wrote:
Mon May 20, 2019 8:29 pm
I'll play a bit more, but if I can't improve the performance to at least match the classic BASIC solution I probably won't pursue it any further.
Progress! I've now got my 'native' (BBC BASIC) BigInt library to evaluate the million-digit Fibonacci number faster than the 'classic BASIC' version: 7 minutes compared with 12 minutes on the same (fairly fast) PC. Not a dramatic improvement, admittedly, but I'm reasonably satisfied because the library is general purpose rather than being in any way optimised for the Fibonacci challenge.

This is the program:

Code: Select all

      HIMEM = PAGE + 20000000
      INSTALL @lib$ + "bigint"
      PROCbiginit

      f0%% = FNbignew(1000000)
      f1%% = FNbignew(1000000)

      TIME = 0
      PROCfibonacci(4784969, f0%%, f1%%)
      *spool fibo1M.txt
      PRINT FNbigstr(f0%%)
      *spool
      PRINT TIME/100 " seconds"
      END

      REM Fibonacci calculation using the doubling algorithm:
      DEF PROCfibonacci(N%, f%%, g%%)
      LOCAL S%, a%%, b%%, c%%, d%%
      S% = N% * LOG((SQR(5) + 1) / 2) + 1
      IF N% = 0 THEN
        a%% = FNbignew(1)
        b%% = FNbignew(1)
        PROCbigval(b%%, "1")
        PROCbigcpy(a%%, f%%) : REM f = 0
        PROCbigcpy(b%%, g%%) : REM g = 1
        ENDPROC
      ENDIF
      a%% = FNbignew(S%) : b%% = FNbignew(S%)
      PROCfibonacci(N% DIV 2, a%%, b%%)
      c%% = FNbignew(S%) : d%% = FNbignew(S%)

      PROCbiguadd(b%%, b%%, c%%)
      PROCbigusub(c%%, a%%, d%%)
      PROCbigumul(d%%, a%%, c%%)   : REM c = a * (b * 2 - a)
      PROCbigumul(a%%, a%%, d%%)
      PROCbigumul(b%%, b%%, a%%)
      PROCbiguadd(d%%, a%%, b%%)   : REM b = a * a + b * b
      IF N% AND 1 THEN
        PROCbigcpy(b%%, f%%)       : REM f = b
        PROCbiguadd(b%%, c%%, g%%) : REM g = b + c
      ELSE
        PROCbigcpy(c%%, f%%)       : REM f = c
        PROCbigcpy(b%%, g%%)       : REM g = b
      ENDIF
      ENDPROC
The library uses 64-bit pointers/handles to represent the big integers. I've tried to leverage 'unique' features of BBC BASIC as far as possible, so internally it makes extensive use of whole-array operations and indirection. For example adding two bigints together is done with the following code (carries between limbs are dealt with separately):

Code: Select all

      c%%() = a%%() + b%%()
This allows loops to be eliminated to a large extent: there is only one FOR...NEXT loop in the entire library! I'm still not sure whether to put in the extra effort to extend the library to cope with signed numbers and other operations such as division; I might set that as a challenge for the BBC BASIC community.
I suspect your underlying big-integer multiplication routines are more than 3 times faster than the code in the classic line-numbered Basic program. This is because the Fibonacci part of the line-numbered Basic code

1. Uses Cassini's identity to eliminate one out of the three multiplications used in each recursive application of the doubling formula compared to what your code does.

2. At the top level of the recursion classic.bas only computes b, thereby eliminating 2 of the 3 multiplications at the last step. This is surprisingly important as that step dominates the running time.

If you include the above two optimisations, I suspect your Fibonacci program will run in under 3 minutes. Note that in visual.bas the routines fibo and fibowork illustrate the same doubling formulas used in the classic.bas code. The comments at the beginning of either program are also helpful to understand the exact formulas for doubling which were employed in the code.

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Mon May 27, 2019 7:08 pm

ejolson wrote:
Mon May 27, 2019 6:38 pm
Note that the visual.bas routines fibo and fibowork illustrate the same doubling formulas used in the classic.bas code. The comments at the beginning of either program are helpful to understand the exact formulas for doubling which were employed in the code.
I'll take a look. I certainly didn't attempt to understand the 'classic BASIC' code - it's a perfect example of the non-readability of spaghetti code using GOTO!

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Mon May 27, 2019 8:47 pm

RichardRussell wrote:
Mon May 27, 2019 7:08 pm
I'll take a look.
I notice that one of the optimisations involves the use of 'biginc' and 'bigdec' routines, which I haven't provided in my library, so that's not something I can instantly implement. But not computing the tuple of Fibonacci values at the top level, when only one is needed, is an easy change which has reduced the execution time to a little under six minutes.

I'm a little concerned that I seem to have chosen a different parameter order for the 'big' arithmetic routines: yours have the output as the first parameter and mine as the last. Is there a convention I should have followed? I'll change mine if appropriate.

jahboater
Posts: 4424
Joined: Wed Feb 04, 2015 6:38 pm

Re: Introduction to BBC BASIC

Mon May 27, 2019 10:11 pm

RichardRussell wrote:
Mon May 27, 2019 8:47 pm
I'm a little concerned that I seem to have chosen a different parameter order for the 'big' arithmetic routines: yours have the output as the first parameter and mine as the last. Is there a convention I should have followed? I'll change mine if appropriate.
It probably doesn't matter, but it is common to have the destination as the first argument. See strcpy() etc, most assemblers,
and of course all the hundreds of GMP and MPFR functions are that way round.

System calls and the standard ABI have the return value in r0 - the first register, that was the first argument .....

Probably just convention though.

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Mon May 27, 2019 10:44 pm

jahboater wrote:
Mon May 27, 2019 10:11 pm
it is common to have the destination as the first argument. See strcpy() etc, most assemblers, and of course all the hundreds of GMP and MPFR functions are that way round.
OK. I knew about Intel assembly language, but I thought that was an anomaly (GAS has the operands the other way around, doesn't it?). The other examples are mostly outside my experience, but I will change my library to accord with the majority convention.
System calls and the standard ABI have the return value in r0 - the first register, that was the first argument .....
True, but I hadn't associated register names/numbers with parameter order.

User avatar
RichardRussell
Posts: 496
Joined: Thu Jun 21, 2012 10:48 am

Re: Introduction to BBC BASIC

Mon May 27, 2019 11:00 pm

Code is now:

Code: Select all

      HIMEM = PAGE + 20000000
      INSTALL @lib$ + "bigint"
      PROCbiginit

      f0%% = FNbignew(1000000)

      TIME = 0
      PROCfibo(4784969, f0%%)
      *spool fibo1M.txt
      PRINT FNbigstr(f0%%)
      *spool
      PRINT TIME/100 " seconds"
      END

      REM Fibonacci calculation using the doubling algorithm:
      DEF PROCfibo(N%, f%%)
      LOCAL S%, a%%, b%%, c%%
      S% = N% * LOG((SQR(5) + 1) / 2) + 1
      a%% = FNbignew(S%) : b%% = FNbignew(S%)
      PROCfibo2(N% DIV 2, a%%, b%%)
      c%% = FNbignew(S%)

      IF N% AND 1 THEN
        PROCbigumul(c%%, a%%, a%%)
        PROCbigumul(a%%, b%%, b%%)
        PROCbiguadd(f%%, c%%, a%%)   : REM f = a * a + b * b
      ELSE
        PROCbiguadd(f%%, b%%, b%%)
        PROCbigusub(c%%, f%%, a%%)
        PROCbigumul(f%%, c%%, a%%)   : REM f = a * (b * 2 - a)
      ENDIF
      ENDPROC

      DEF PROCfibo2(N%, f%%, g%%)
      LOCAL S%, a%%, b%%, c%%, d%%
      S% = N% * LOG((SQR(5) + 1) / 2) + 1
      IF N% = 0 THEN
        a%% = FNbignew(1)
        b%% = FNbignew(1)
        PROCbigval(b%%, "1")
        PROCbigcpy(f%%, a%%) : REM f = 0
        PROCbigcpy(g%%, b%%) : REM g = 1
        ENDPROC
      ENDIF
      a%% = FNbignew(S%) : b%% = FNbignew(S%)
      PROCfibo2(N% DIV 2, a%%, b%%)
      c%% = FNbignew(S%) : d%% = FNbignew(S%)

      PROCbiguadd(c%%, b%%, b%%)
      PROCbigusub(d%%, c%%, a%%)
      PROCbigumul(c%%, d%%, a%%)   : REM c = a * (b * 2 - a)
      PROCbigumul(d%%, a%%, a%%)
      PROCbigumul(a%%, b%%, b%%)
      PROCbiguadd(b%%, d%%, a%%)   : REM b = a * a + b * b
      IF N% AND 1 THEN
        PROCbigcpy(f%%, b%%)       : REM f = b
        PROCbiguadd(g%%, b%%, c%%) : REM g = b + c
      ELSE
        PROCbigcpy(f%%, c%%)       : REM f = c
        PROCbigcpy(g%%, b%%)       : REM g = b
      ENDIF
      ENDPROC

jahboater
Posts: 4424
Joined: Wed Feb 04, 2015 6:38 pm

Re: Introduction to BBC BASIC

Mon May 27, 2019 11:56 pm

RichardRussell wrote:
Mon May 27, 2019 10:44 pm
GAS has the operands the other way around, doesn't it?
:) Yes, but I think GAS is itself the anomaly :)

The ARM CPU on the Pi has the destination on the left.

Return to “Other programming languages”