Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LOG(2) inaccurate (slightly) #363

Open
Jaxartes opened this issue Nov 6, 2022 · 4 comments
Open

LOG(2) inaccurate (slightly) #363

Jaxartes opened this issue Nov 6, 2022 · 4 comments

Comments

@Jaxartes
Copy link
Contributor

Jaxartes commented Nov 6, 2022

The result of LOG(2) in BASIC is a little bit off. It's debatable whether this is significant, since floating point numbers are generally imprecise. The result looks right when printed, but as seen in memory it's a little bit different from what the Commodore 64 calculates and from what it should be.

On both, "PRINT LOG(2)" shows .693147181. There are a few ways to see it's different:

  • "PRINT 1000*(.7-LOG(2))" gives different results: 6.85281919 on X16, 6.85281931 on C64, and 6.85281928 on C128. An "ideal" result would be 6.85281944. C64's result is as close as it can be. X16's is more off.
  • "PRINT 2↑15" gives 32768.0001 on X16 but not on C64. (This doesn't mean much. )
  • Using the attached program (
    fp-show.bas.txt) to show how LOG(2) is represented in memory. On X16 the mantissa is "B1 72 17 F9" while on C64 the mantissa is "B1 72 17 F8". The natural log of 2, in hex, is ".B17217F7D1CF79..." so the C64's value is closer. (The attached program has a bug in displaying the sign, but that's not important here.)

Seen with current ROM code (5d8ba9f) and also on rather older ROM (b6a0f0c). Seen with LOG(2) and LOG(2+2↑-30) and nothing else I've tried, including LOG(2.000001).

@MJoergen
Copy link
Contributor

MJoergen commented Nov 7, 2022

Interesting. I did change the ADD, MULT, and SQR routines in the math library to more optimized versions (see commit 005c504) two years ago. It could be worth looking into, whether this change is the source of the error.

I don't have the opportunity to test this myself at the moment, so this is just informational, in case someone else picks up from here.

@Jaxartes
Copy link
Contributor Author

Jaxartes commented Nov 8, 2022

Confirmed in testing that with commit 005c504, the result of "PRINT 1000*(.7-LOG(2))" changed from 6.85281931 (as on C64) to 6.85281919 (as now).

@Jaxartes
Copy link
Contributor Author

Jaxartes commented Nov 14, 2022

Strangely, it appears 'fmult' is more accurate than before commit 005c504 (at least in one relevant case) but something in 'log' that didn't change was wrong. Or else there's something strange about how 'facov' (the overflow/rounding byte) is handled.

In both the current code and before 005c504, LOG(2) ends with multiplying 'log2' by the following value in 'fac': 81 80 00 00 00 80 (where the last byte I've listed is that in 'facov' though it's not contiguous in memory). The result given for that is different, 80 B1 72 17 F8 2C with the old code and 80 B1 72 17 F8 B0 with the new.

Assuming 'facov' is a straightforward 8 bit extension of the mantissa of FAC then the new result is more accurate. Is that assumption right? I don't know.

Data:
80 31 72 17 f8 .. = 0.6931471806019545 (log2 in memory)
81 80 00 00 00 80 = 1.0000000002328306 (fac passed to fmult)
80 B1 72 17 F8 2C = 0.6931471806419722 (old code, better LOG(2))
80 B1 72 17 F8 B0 = 0.6931471807620255 (new code, better product)

@MJoergen
Copy link
Contributor

I seem to remember that 'facov' indeed is just the eight following bits of the accumulator, used for extra accuracy. Or maybe 'facov' really only contains one or two bits (rather than eight), I'm not sure.

Now, the line "fac passed to fmult" should contain the exact real value 1.0, since this should be the log base 2 of the input value. I believe the value shown is the result of a lenghty calculation, so presumably there is some accumulated rounding error in this preceding calculation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants