I need to know the real way to do this. BING AI and ChatGPT keep giving me different solutions, and only this last one works. Or seems to work.

I was amused that the BING AI suggested using DEF FN to create this function on a BASIC without LN.

DEF FNLN(x)
=LOG(x) / LOG(2.71828)

Changing the X to uppercase allows this to work on the CoCo. The results are close — are they close enough? Would more decimal places in the LOG value help?

Where are the math people?

Like this:

LikeLoading...

Related

12 thoughts on “Getting LN in BASIC on a machine that only has LOG”

For anyone not aware, mathematically you can find the base B logarithm of X by using LOG(X)/LOG(B) where it doesn’t matter what base those two LOGs are in as long as it’s the same for both. (So natural log, bast 10 log, base PI log, whatever.)

The LOG function is usually implemented with a taylor series of some kind and depending on the value being calculated, has more or less error in the result. Then add in the division of two values with some amount of error and the resulting error gets larger. More digits for the value of e should help, but even better would be to look up the correct value of LN(e) and put that in to 9 or so significant digits since that is just a constant. Basically, if you remove one LOG calculation, you remove a source of error and also speed up the calculation.

Whatever you do, you should expect the lowest order digits to be off by some amount after the division due to the nature of floating point calculation.

If you’re doing the calculation a lot, this would indeed be a good use case for DEF FN.

This will drive you crazy, because the LOG function on the CoCo is LN on the BBC.
The CoCo doesn’t have the BBC LOG function.

On the bbc, these two are equivalent:
PRINT LOG(123)
PRINT LN(123)/LN(10)

Because BBC LN is CoCo LOG you would want two user defined functions, defined in terms of CoCo LOG. Something like:
DEF FN BBCLN(X)=LOG(X)
DEF FN BBCLOG(X)=LOG(X)/LOG(10)

And in the code you are porting, replace the bbc functions with the user-defined functions. Otherwise keeping track of LN vs LOG vs LOG will make you crazy.

But I assume function names can’t be six characters long….

Well, poo. This is all so far beyond my limited mental capabilities. Thank you for this information. This stuff comes easy for so many folks, but I struggle. I think Barbie was right!

Oh, yep, the BBC code only uses LN once and doesn’t use LOG at all.
So, yes, just using the native CoCo LOG should be the simplest approach (until 3 years later when you try go back the other way!)

Understand the program? No, sorry.
Understand the individual commands? Mostly.
I had a BBC emu and a CoCo emu open side by side.
And the BBC docs and the CoCo docs open side by side.
I just tested RND and LN/LOG, etc side by side with one liners until I understood the difference between the BBC and the CoCo.

Nicely done. I found an online BBC Emulator and a manual and tested their RND, and looked up what LN is. I never looked up what the CoCo’s LOG was, just ass-u-me’d LOG was LOG. #fail

Loading...

Sebastian Tepper

Instead of implementing LN(X) = LOG(X) / LOG (2.71828183)
(where E has been rounded to 9 significant digits because that is the actual number of digits handled in the 5-byte COCO floating point implementation), a fastest solution is to precalculate the denominator and MULTIPLY by its reciprocal instead (multiplication is usually faster than division).

So: LN(X) = LOG(X) * 2.30258509

Again with the special constant rounded to 9 significant digits.

In this case, it turns out the LN in the BBC is the LOG in the CoCo so no conversion is needed. But man, every little bit of speed will help with all the math this thing is doing.

William AstleFor anyone not aware, mathematically you can find the base B logarithm of X by using LOG(X)/LOG(B) where it doesn’t matter what base those two LOGs are in as long as it’s the same for both. (So natural log, bast 10 log, base PI log, whatever.)

The LOG function is usually implemented with a taylor series of some kind and depending on the value being calculated, has more or less error in the result. Then add in the division of two values with some amount of error and the resulting error gets larger. More digits for the value of e should help, but even better would be to look up the correct value of LN(e) and put that in to 9 or so significant digits since that is just a constant. Basically, if you remove one LOG calculation, you remove a source of error and also speed up the calculation.

Whatever you do, you should expect the lowest order digits to be off by some amount after the division due to the nature of floating point calculation.

If you’re doing the calculation a lot, this would indeed be a good use case for DEF FN.

Jerry StrattonYes, this is even covered in Getting Started with Extended Color BASIC, on page 176.

Sean Patrick ConnerThey are close enough. You could try using 2.7182818284 but at a certain point, adding digits won’t help.

jmurphyThis will drive you crazy, because the LOG function on the CoCo

isLN on the BBC.The CoCo doesn’t have the BBC LOG function.

On the bbc, these two are equivalent:

PRINT LOG(123)

PRINT LN(123)/LN(10)

Because BBC LN

isCoCo LOG you would want two user defined functions, defined in terms of CoCo LOG. Something like:DEF FN BBCLN(X)=LOG(X)

DEF FN BBCLOG(X)=LOG(X)/LOG(10)

And in the code you are porting, replace the bbc functions with the user-defined functions. Otherwise keeping track of LN vs LOG vs LOG will make you crazy.

But I assume function names can’t be six characters long….

–jmurphy

Allen HuffmanPost authorWell, poo. This is all so far beyond my limited mental capabilities. Thank you for this information. This stuff comes easy for so many folks, but I struggle. I think Barbie was right!

Allen HuffmanPost authorLooks like there is on instance of LN in the BBC code, so that should be okay to change to LOG for CoCo.

jmurphyOh, yep, the BBC code only uses LN once and doesn’t use LOG at all.

So, yes, just using the native CoCo LOG should be the simplest approach (until 3 years later when you try go back the other way!)

–jmurphy

Allen HuffmanPost authorSo … do you understand how this actually works?!

jmurphyUnderstand the program? No, sorry.

Understand the individual commands? Mostly.

I had a BBC emu and a CoCo emu open side by side.

And the BBC docs and the CoCo docs open side by side.

I just tested RND and LN/LOG, etc side by side with one liners until I understood the difference between the BBC and the CoCo.

–jmurphy

Allen HuffmanPost authorNicely done. I found an online BBC Emulator and a manual and tested their RND, and looked up what LN is. I never looked up what the CoCo’s LOG was, just ass-u-me’d LOG was LOG. #fail

Sebastian TepperInstead of implementing LN(X) = LOG(X) / LOG (2.71828183)

(where E has been rounded to 9 significant digits because that is the actual number of digits handled in the 5-byte COCO floating point implementation), a fastest solution is to precalculate the denominator and MULTIPLY by its reciprocal instead (multiplication is usually faster than division).

So: LN(X) = LOG(X) * 2.30258509

Again with the special constant rounded to 9 significant digits.

Allen HuffmanPost authorVery nice!

In this case, it turns out the LN in the BBC is the LOG in the CoCo so no conversion is needed. But man, every little bit of speed will help with all the math this thing is doing.