Jump to content
IGNORED

Altirra Extended BASIC


Recommended Posts

2 hours ago, DrVenkman said:

In a FB discussion with some friends recently we were discussing mathematical implementations for numerical modeling (*) and happened to run across a support article from Apple briefly discussing how they have moved the calculation engine for their Numbers spreadsheet to a 128-bit base. That got me wondering how well my various calculator apps, programs and old computers would be able to calculate the simple expression "2^128", and how many decimal places out the scientific notation the errors would creep in. 

 

 

The current version of Excel expresses the result (to 11 decimal places) as 3.40282366921E+38, which is the same result provided by my HP-48G and my iOS HP emulators. (**)

 

Altirra Extended BASIC has a markedly more accurate result. Still not objectively "correct", but a couple decimal places closer.

 

I don't expect anyone is coding astronomical, cosmological or subatomic problems via numerical modeling on our 8-bits, but it's always nice to see increased accuracy in the math when possible.

The reason for this is rounding: all results in ATXBasic's math pack are rounded. The AltirraOS math pack does this as well, so you will get similar results with Atari BASIC under that OS. I think there was one corner case of double-rounding in the AltirraOS math pack that I couldn't avoid for code size reasons but was able to fix in ATXBasic.

 

Power operations in Atari BASIC compatible interpreters are implemented as 10^(log(x) * y). The intermediate log(2) result computed by ATXBasic is 0.3010299956, which is 1 ulp off from correct -- should be 0.3010299957. Still, not a bad end result compared to IEEE 754 double arithmetic, which has ~15 digit precision. Atari decimal FP has 9-10 digits of precision which limits the best possible result from this formula to 3.40282371E+38.

 

Note that Turbo-Basic XL and ATXBasic have an optimization where integer powers are converted to multiplication trees, which is both faster and more accurate. It doesn't kick in this case because the exponent is larger than two digits, and Turbo-Basic XL actually gives an overflow error (!), but you can see the result by manually squaring 2^64. This does manage to give a fully correct result within representable precision.

1 hour ago, billkendrick said:

Does AEB support bare "NEXT"s (no avar), like I recall TBXL supporting? (The docs don't show the avar being optional)

No, just tried it in Turbo-Basic XL 1.5 and it isn't accepted there either.

 

  • Like 2
Link to comment
Share on other sites

7 hours ago, DrVenkman said:

I haven't spent much time coding in the last, oh, 3 decades or so, but it's wonderful to see this version of BASIC being maintained and improved by the one singular living person who probably knows best how the Atari hardware and software works and cooperates together. :)

 

In a FB discussion with some friends recently we were discussing mathematical implementations for numerical modeling (*) and happened to run across a support article from Apple briefly discussing how they have moved the calculation engine for their Numbers spreadsheet to a 128-bit base. That got me wondering how well my various calculator apps, programs and old computers would be able to calculate the simple expression "2^128", and how many decimal places out the scientific notation the errors would creep in. 

 

The current version of Excel expresses the result (to 11 decimal places) as 3.40282366921E+38, which is the same result provided by my HP-48G and my iOS HP emulators. (**)

 

Atari BASIC, using the built in FP package gets bitten by rounding errors:

 

IMG_1822.thumb.JPG.ef6ddaa58ad6698d859746f6c37766fe.JPG

 

Altirra BASIC version 1.5 and BASIC XE seems to also rely on the same built-in FP package, or at least one with the same inaccuracies with large numbers:

 

IMG_1825.thumb.JPG.1dd97cac01633421c746973cefe9e283.JPG

 

Altirra Extended BASIC has a markedly more accurate result. Still not objectively "correct", but a couple decimal places closer. 

 

IMG_1824.thumb.JPG.cb32b36d36585c8f616b3eed2936f428.JPG

 

I don't expect anyone is coding astronomical, cosmological or subatomic problems via numerical modeling on our 8-bits, but it's always nice to see increased accuracy in the math when possible. 

 

ALSO: I probably should break down and start playing with Altirra Extended BASIC some more - looks like it's already great, on its way to pretty spectacular. :) 

 

(*) I last coded some orbital mechanics simulations as an undergrad studying aerospace engineering around 1988 or 1989. I coded in OSS Personal Pascal on my 1040ST because ST BASIC sucked ass and gave me terribly inaccurate results.

 

(**) The actual value, expressed as a number, is big. I mean, really freaking big: 340,282,366,920,938,000,000,000,000,000,000,000,000  ? 

I just tried Fast BASIC 4 FP and it looks like its the winner correct to 8 decimal places rather than 7! 

  • Like 2
Link to comment
Share on other sites

Discovering the Player/Missile Graphics commands, which are exciting. (Had never used BASIC XL before, but knew of it, thanks to Compute! books I had as a kid.)

 

I'm realizing that PMG stuff gets turned off when the program ends (last line executed, or END issued). Makes it a bit hard to toy with things in immediate mode. Noticed that, e.g., "PMMOVE 0,100" results in an unexpected "Error-  30 ?Label at line NNN". So I guess "STOP" it is...

Link to comment
Share on other sites

PS to get it to work on my The Ultimate SD Cart, I had to use the little "RomToCar" (html+JavaScript (!)) tool to convert the "atxbasic.bin" to a suitable "CAR" file. (Slightly different header, I guess?)

 

Also, these PMG commands aren't in the online help, and also not noted under the list of non-Atari BASIC-compatible commands in the PDF docs.

 

Oh, and listing the version # in the online help would be groovy. :)

Link to comment
Share on other sites

Hi!

8 hours ago, Steve Mynott said:

I just tried Fast BASIC 4 FP and it looks like its the winner correct to 8 decimal places rather than 7! 

Well, FastBasic cheats a little, by parsing the expression as "integer power", it simply uses a multiplication tree to calculate the result, same as TuboBasicXL and Altirra Extended Basic for numbers less than 100.

 

You can test this code to see the difference, as we can force a floating point exponent:


  ? 2^128   ' Integer exponent

  ? 2^128.0  ' FP exponent

 

Of course, if you use a better math pack (for example, the excellent Altirra Mathpack), you get the best results:

image.png.9f1eb8938dc96f03621f80f719f544e1.png

 

I don't like the power optimization on runtime, because it can cause discontinuities in the function, this leads to errors in algorithms and plots, see this:

image.png.27ae75a91fc6f13664c2b4c626938056.png

 

The power function is not monotonic!

 

And in TurboBasicXL it is worse:

image.png.4b20ca1d2ecd0c044df0cd357fd10824.png

 

But I agree, that because you don't have an integer data type in Altirra Extended Basic, this optimization is the best possible.

 

Have Fun!

 

  • Like 3
Link to comment
Share on other sites

49 minutes ago, dmsc said:

I don't like the power optimization on runtime, because it can cause discontinuities in the function, this leads to errors in algorithms and plots, see this:
The power function is not monotonic!

Yeah, this is basically the much faster replacement for the Atari BASIC rounding hack. It's so much faster than the full formula that it can't be ignored since TBXL is used for so many games.

 

It might be possible to retune the LOG10/EXP10 constants to improve the accuracy and thus range of monotonicity -- think currently it's just using the same constants as the AltirraOS math pack, which has to worry about compatibility with the rounding hack, whereas ATXBasic's math pack doesn't. PLYEVL probably also evaluates in the wrong order for accuracy given the values passed into it.

 

I'm not actually overly concerned about accuracy/monotonicity and am fine with a 1ulp error on non-identity values for complex functions, but it's always nice to have. The more pragmatic reason for the improved accuracy is that it's a way to get to "at least as good as Atari BASIC / TBXL" without copying the specific errors from the original math pack, which is in turn difficult to do without actually copying bits from the math pack, which is a no-no here.

 

  • Like 3
Link to comment
Share on other sites

Hi!

18 hours ago, phaeron said:

Yeah, this is basically the much faster replacement for the Atari BASIC rounding hack. It's so much faster than the full formula that it can't be ignored since TBXL is used for so many games.

 

It might be possible to retune the LOG10/EXP10 constants to improve the accuracy and thus range of monotonicity -- think currently it's just using the same constants as the AltirraOS math pack, which has to worry about compatibility with the rounding hack, whereas ATXBasic's math pack doesn't. PLYEVL probably also evaluates in the wrong order for accuracy given the values passed into it.

 

I'm not actually overly concerned about accuracy/monotonicity and am fine with a 1ulp error on non-identity values for complex functions, but it's always nice to have. The more pragmatic reason for the improved accuracy is that it's a way to get to "at least as good as Atari BASIC / TBXL" without copying the specific errors from the original math pack, which is in turn difficult to do without actually copying bits from the math pack, which is a no-no here.

 

I tried brute-forcing the constants around a min-max approximation, minimizing the relative error, constraining that EXP10(1)=10 and EXP10(0)=1 exactly and searching for the most zeroes in the coefficients (to minimize runtime). Problem is, my code does not emulate exactly the rounding done in your math-pack, so the result is not 100% accurate, but good enough.

 

My current best coefficients are (first is always 1 with the constrain EXP10(0)=1):

  2.65094503
  2.03478568
  1.17018241
  0.5447325000
  0.1921384000
  0.0919451600
 -0.002005300000
  0.0146910000

With those, I got a maximum error of 9.99948e-09, this is one ULP at small values of X, this is the plot of relative error.

image.thumb.png.537f38be8e26efa796e1b51751e5a9df.png

 

I also tried searching for sets of 9 coefficients (one less than current), there best error is 7*10^-8.

 

Link to comment
Share on other sites

18 hours ago, dmsc said:

I tried brute-forcing the constants around a min-max approximation, minimizing the relative error, constraining that EXP10(1)=10 and EXP10(0)=1 exactly and searching for the most zeroes in the coefficients (to minimize runtime). Problem is, my code does not emulate exactly the rounding done in your math-pack, so the result is not 100% accurate, but good enough.

Do you know the case that differs? The trickiest case is destructive cancellation during addition/subtraction, I seem to recall some icky cases involving a one digit pair exponent difference with a borrow where it was easy for the result to be over-rounded, because the rounding bit is injected into the carry but during the subtraction but the borrow then requires one normalization shift, which shifts the rounding pair back into range. Don't remember how/if I managed to solve this.

 

Link to comment
Share on other sites

Hi!

4 hours ago, phaeron said:

Do you know the case that differs? The trickiest case is destructive cancellation during addition/subtraction, I seem to recall some icky cases involving a one digit pair exponent difference with a borrow where it was easy for the result to be over-rounded, because the rounding bit is injected into the carry but during the subtraction but the borrow then requires one normalization shift, which shifts the rounding pair back into range. Don't remember how/if I managed to solve this.

I tried about 24 million adds/subs and 50 mullion multiplications, the only differing case was on normalization after add:

image.thumb.png.6206861bf1f7626fba767d64c4e4910a.png

 

Here I was getting 101 as result, but your code does not round up.

 

Also, I discovered a bug in my SUB implementation, I was rounding on scaling down, but that does not work when the end part is exactly 0.5000... (on sub, you must round down, on add, round up), so your code was correct.

 

Have Fun!

 

 

Link to comment
Share on other sites

On 6/30/2019 at 7:40 PM, dmsc said:

Hi!

Well, FastBasic cheats a little, by parsing the expression as "integer power", it simply uses a multiplication tree to calculate the result, same as TuboBasicXL and Altirra Extended Basic for numbers less than 100.

 

I wouldn't call this cheating. Actually, what you want to do is to split off the integer part, use a multiplication tree for it, and then use the log/exp formula for the fractional part to get consistent results.

Link to comment
Share on other sites

All this discussion of mathematical precision has gotten me motivated - or at least as motivated as I can be at my age. I’m going to try to convert my undergraduate aerospace engineering orbital mechanics assignment into Altirra Extended BASIC from the original OSS Personal Pascal, originally programmed on my ST in September 1988. 

Yes, at one point my brain understood this math. ? (These pics are snips of the handwritten notes I made about the Runge-Kutte method to solve the time-step equations and a couple pages of the Pascal code. This will be fun - assuming my motivation survives my short attention span and multiple hobbies). 

 

A6B30A22-5382-42B6-A7B9-5A819CE5F3F2.jpeg

 

3AD2289B-3468-4505-8DBB-C084F08B90F3.jpeg

 

0C3AB804-1B1F-4C9D-84D4-E98416E76426.jpeg

  • Like 4
Link to comment
Share on other sites

Hi again!

On 7/2/2019 at 4:21 AM, phaeron said:

Do you know the case that differs? The trickiest case is destructive cancellation during addition/subtraction, I seem to recall some icky cases involving a one digit pair exponent difference with a borrow where it was easy for the result to be over-rounded, because the rounding bit is injected into the carry but during the subtraction but the borrow then requires one normalization shift, which shifts the rounding pair back into range. Don't remember how/if I managed to solve this.

I fixed my code so that it produces the same results that the Altirra math-pack and re-run the optimization for the EXP10 coefficients. This time, I minimized the maximum relative error and the mean relative error over small intervals, this is slower but produces stabler results. Also, I tried to get the most zeroes in the coefficients possible.

The best turned out this:

		.byte		$3F, $01, $47, $00, $00, $00 ;    0.0147
		.byte		$7E, $20, $30, $00, $00, $00 ;   -0.002030
		.byte		$3F, $09, $19, $68, $00, $00 ;    0.091968
		.byte		$3F, $19, $21, $32, $00, $00 ;    0.192132
		.byte		$3F, $54, $47, $30, $44, $00 ;    0.54473044
		.byte		$40, $01, $17, $01, $83, $62 ;    1.17018362
		.byte		$40, $02, $03, $47, $86, $04 ;    2.03478604
		.byte		$40, $02, $65, $09, $44, $76 ;    2.65094476
		.byte		$40, $02, $30, $25, $85, $14 ;    2.30258514
		.byte		$40, $01, $00, $00, $00, $00 ;    1

This is a plot of the mean interval error (this is the mean error over 1M numbers) with respect to the correctly rounded result, about 10% better than the original:

image.thumb.png.94926ae9dd611dfcba30e4dd5385d17f.png

Also, zooming in at the end of the interval you see that this gives a lot better results near 1.0, this makes EXP10 more stable around integer values.

image.thumb.png.e6c011a693f65c467c1e6b9791729caf.png

I tested the coefficients in your Altirra Extended Basic implementation, average runtime for EXP10 went from 21347 to 20351 cycles, about 5% faster, and testing over 870000 values from 0.01 to 1.0 mean relative error went from 2.6789621e-09 to 2.4933891e-09.

 

Over the weekend I will try to optimize LOG10, for this I will need to implement division on my code :)

 

Have Fun!

 

  • Like 3
Link to comment
Share on other sites

That's some really great work, but I should fix that rounding issue first in case it influences the results. That particular case doesn't look too bad, as it's in the addition renormalization code and I should be able to re-round the result with a slightly altered rounding constant. It'll be off by a tiny amount, but the ATXBasic math pack doesn't do all out round-to-nearest-even-with-sticky-bits kind of full rounding anyway.

 

Link to comment
Share on other sites

Hi!

On 7/4/2019 at 12:59 AM, phaeron said:

That's some really great work, but I should fix that rounding issue first in case it influences the results. That particular case doesn't look too bad, as it's in the addition renormalization code and I should be able to re-round the result with a slightly altered rounding constant. It'll be off by a tiny amount, but the ATXBasic math pack doesn't do all out round-to-nearest-even-with-sticky-bits kind of full rounding anyway.

Don't worry, I can re-run the optimizations after you fix the rounding, I suspect the result will be about the same.

 

Have Fun!

Link to comment
Share on other sites

  • 2 years later...
3 hours ago, a8isa1 said:

Is there a way to coax Altirra Extended BASIC and SDX to play together?  When I try via AVGCart the language seems to work but I can't access a disk. When I make the attempt two copies of the title and copyright notice appear.

For some reason, SDX resets the MaxFlash cartridge bank when handling I/O. I have some ideas on how to work around this but no fix yet.

  • Like 2
Link to comment
Share on other sites

  • 3 weeks later...
  • 6 months later...

Somehow I had missed this project until now (thanks to a link on a thread about the 578NUC+ and its Basic XE incompatibility).  Very nice!  I haven't really written anything in any form of BASIC in a very long time, but this is very handy to have.  Altirra Extended BASIC seems a good candidate to replace other BASIC languages as a new standard.

 

Link to comment
Share on other sites

  • 3 months later...

Recently I experimented with TBXL 1.5 and found following feature not supported by Altirra BASIC.

Double Quotes

Double quotes are allowed in print statements. Whenever you want a quote in a print statement put in double quotes.
EXAMPLE:
30 ? "SHE SAID ""GOODBYE"" AND SLAMMED THE DOOR"

https://atariwiki.org/wiki/attach/Turbo-BASIC XL/TURBO-BASIC_XL-Expanded_Documentation.pdf

Could you implement it for compatibility?

It would be nice to have possibility of using EOL ($9B) chars in strings in similar way - lets say by using double ESC ($1B) sign...

 

Edit: It would be useful to embed machine code.

Edited by mono
grammar and note
Link to comment
Share on other sites

Altirra Extended BASIC does support double-double quote escaping since it aims for TBXL-compatibility. Altirra BASIC doesn't support it, but that's because Atari BASIC didn't and there's no space in the ROM for it anyway.

 

Note that the restriction of certain characters in strings is in the parser and lister. BASIC's execution engine doesn't actually care about any particular characters in the string, so it is possible to POKE the desired character into the program string after it is created. This results in a program that can't be cleanly LISTed and re-ENTERed, but that's less of a concern with modern methods of writing BASIC programs.

 

Inline asm is probably not something I'm likely to add to the interpreter, because there's not really a precedent in the Atari BASIC or TBXL-derived languages, and BASIC's propensity for relocating the program text segment makes it hard to use any embedded asm without copying it anyway. It's something that would be more useful and easier to add to a _compiler_, but I haven't written a BASIC compiler so far. Part of the reason for that is that although despite doing work on BASIC interpreters, I don't actually use BASIC myself for much other than testing, any significant programs I end up writing directly in asm.

 

  • Like 2
Link to comment
Share on other sites

  • 4 months later...

So I did Ahl's benchmark test with real hardware, in this case my 1200XL Rev 10 OS, 256k memory.

It took 290 seconds to complete (v1.54 & v1.28). With BASIC XE it took 48 seconds.

 

I'm assuming that the Altirra emulator has built-in FP package that Altirra basic can access, and hence,

is no better than atari basic with real hardware ? Thanks.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...