stardot / MatrixBrandy

Matrix Brandy BASIC VI for Linux, Windows, MacOSX
http://brandy.matrixnetwork.co.uk/
44 stars 8 forks source link

numeric issue: x86_64 vs arm #45

Closed scruss closed 5 years ago

scruss commented 5 years ago

On Raspberry Pi, this program gives the expected result:

$ sbrandy -size 48000000 classic_small-test.bas
? 100
354224848179261915075

but on x86_64 I get:

$ sbrandy -size 48000000 classic_small-test.bas
Tried to take square root of a negative number at line 8610

A little bit of shotgun debugging (adding 8605 PRINT " *** F0: "; F0) sets variable F0 to 1.07374182e+09 where the same code on x86_64 sets it to -1.07374182e+09

Systems are:

soruk42 commented 5 years ago

Interesting... it works OK on my ancient Wheezy Raspian installation (RasPi2), and fails identically to your x64_64 error on x86 (32-bit). So, it's not a bitness thing.

soruk42 commented 5 years ago

It seems the INT() function is at fault. F=9.1E15 PRINT INT(F0/2) ...positive on RasPi ( = &7FFFFFFF) ...Negative on x86 and x86_64 ( = &80000000)

The conversion to integer is implemented as a C cast to int32. And, I found this: https://stackoverflow.com/questions/20453449/sign-changes-when-going-from-int-to-float-and-back which is EXACTLY the same issue,.

On RISC OS 3.7, BASIC V complains "Number too big", BASIC VI (*BASIC64) gives a floating-point exception.

I think that program is assuming the variables are integers (except those defined as doubles in line 241 - which I've REMed out on my copy)

soruk42 commented 5 years ago

The real bug is, of course, INT accepting an out-of-range value. I've pushed a commit that prevents this (replicates BBC Micro and RISC OS behaviour).

To make this Fibonacci program work, delete lines 8520 to 8600 inclusive, and in its place, add: 8520 F0=&7FFFFFFF

soruk42 commented 5 years ago

I've reworked the change. Backed out the one I committed above, and modified the TOINT macro (for any situation where a float is changed to an int) to a function which will report "Number too big" if it would overflow.