paladin-t / my_basic

A lightweight BASIC interpreter written in standard C in dual files. Aims to be embeddable, extendable and portable.
http://paladin-t.github.io/my_basic/
MIT License
507 stars 118 forks source link

Floats #65

Closed invpe closed 2 years ago

invpe commented 2 years ago

Hello, i just did a small test on three separate architectures running a simple BAS script.

First the C++ code:

#include <stdio.h>
#include <string>
int main(int argc, char*argv[])
{
 float a = 123.0/321.0*321.321123;
  std::string b = std::to_string(a);
  printf("%f\n",a);
  printf("%s\n", b.data());

return 0;
}

Results:

x86_64 GNU/Linux
123.123047
123.123047
armv7l GNU/Linux
123.123047
123.123047
ESP32-WROOM-32D (4MB) 
123.123047
123.123047

Then i turned to run exactly the same operation with using mybasic, the script is as follows:

A = 123.0/321.0*321.321123
B = STR(A)
PRINT A;
PRINT B;

Results:

x86_64 GNU/Linux
123.123
123.123
armv7l GNU/Linux
123.123
123.123
ESP32-WROOM-32D (4MB) 
123.12305
123.12305

Why is there a discrepancy in the results, what can cause that? Looks like rounding (123.123047 to 123.12305) is happening.

paladin-t commented 2 years ago

There are a few things that make it different.

First, real_t is defined as float as default in MY-BASIC (you could change it to double). Second, float and double evaluate differently, i.e:

float a = 123.0  / 321.0  * 321.321123;  // Calculated in `double`, narrowed into `float`.
float b = 123.0f / 321.0f * 321.321123f; // Calculated in `float`.
printf("%f\n%f\n", a, b);

results to:

123.123047
123.123055

Third, MY-BASIC uses "%g" as default to output real_t (you could change it also).

invpe commented 2 years ago

Appreciate these details, thanks v much.

invpe commented 2 years ago

Reopening as i will be commencing further testing, still don't understand however why mybasic without any changes spits out different results on different architectures, even though a C++ execution returns them consistent.

invpe commented 2 years ago

Closing, issue found to be MB_MANUAL_REAL_FORMATTING enabled in different architecture.