Posts: 3,965
Threads: 176
Joined: Apr 2022
Reputation:
219
(07-10-2023, 01:12 AM)Jack Wrote: bplus, the point was to show any buggy output by QB64 native double to string conversion as in your example Print (1D+17) * (1D+17)
as you can see in your output you have two 1D+22 and no 1D+23, also you have two 1D+28 and no 1D+29
using the C snprintf function would show them correctly
It did, and I missed seeing the 22/23 and 28/29 repeats doing it the 2nd way! Definitely something buggy!
b = b + ...
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
(07-09-2023, 06:32 PM)mnrvovrfc Wrote: Try this in QBasic. If the output is the same then it stays fellas.
I went into NeptuneOS "Ada", which is based on Debian v11 (no longer the "stable", now "oldstable", this was since last month). It had DOSBOX installed there, so I went ahead and copied my installation of M$ QuickBASIC v4.5 left long ago by computers that used to run WindowsXP. I created the program as suggested in this thread. It was a wrangle to get this screenshot because while DOSBOX is into QuickBASIC, it takes over the mouse and window. The mouse goes too darned fast. Must hit [WIN] key to open the desktop menu and fire up KDE Spectacle to get the screenshot, set three-second delay for taking the shot of the window under the mouse pointer. Set the trap and then set the mouse cursor inside DOSBOX window.
Posts: 3,965
Threads: 176
Joined: Apr 2022
Reputation:
219
If according to what jack says is true, that the following code fixes the error when printing a double, THEN this could be fixed with the next update of QB64pe.
Correct?
Code: (Select All) qbs *qbs_str(double value){
static qbs *tqbs;
tqbs=qbs_new(32,1);
char buf1[32];
static int32 l, i,j,digits,exponent, digits1, exponent1;
sprintf((char*)&buf1,"% .14e", value);
sprintf((char*)&qbs_str_buffer,"% .15e", value);
exponent=atoi((char*)&qbs_str_buffer[19]);
exponent1=atoi((char*)&buf1[18]);
digits=17;
while((qbs_str_buffer[digits]=='0')&&(digits>0)) digits--;
digits1=16;
while((buf1[digits1]=='0')&&(digits1>0)) digits1--;
if(((digits-digits1)>1)&&(exponent==exponent1)){
for(i=1;i<17;i++){
qbs_str_buffer[i]=buf1[i];
}
qbs_str_buffer[17]='0';
digits=17;
while((qbs_str_buffer[digits]=='0')&&(digits>0)) digits--;
}
tqbs->chr[0]=qbs_str_buffer[0]; // copy sign
if(exponent==0){
for(i=1;i<=(digits);i++){
tqbs->chr[i]=qbs_str_buffer[i];
}
if(tqbs->chr[digits]=='.') // if no digits after . then nip it
tqbs->len=digits; // by zero terminating
else
tqbs->len=digits+1; // terminate
}
else if(exponent<0){
if((digits-exponent)>=19){ // use sci format
for(i=1;i<=digits;i++){
tqbs->chr[i]=qbs_str_buffer[i];
}
if(tqbs->chr[digits]=='.'){
tqbs->chr[digits]='D';
sprintf((char*)&tqbs->chr[digits+1],"%+03d", exponent);
l=digits+1;
while((tqbs->chr[l])!=0) l++;
tqbs->len=l;
}
else{
tqbs->chr[digits+1]='D';
sprintf((char*)&tqbs->chr[digits+2],"%+03d", exponent);
l=digits+2;
while((tqbs->chr[l])!=0) l++;
tqbs->len=l;
}
}
else{
tqbs->chr[1]='.';
for(i=2;i<=abs(exponent);i++){
tqbs->chr[i]='0';
}
tqbs->chr[abs(exponent)+1]=qbs_str_buffer[1]; // first non-zero digit
j=3; // skip decimal point
for(i=abs(exponent)+2;i<(abs(exponent)+digits);i++){
tqbs->chr[i]=qbs_str_buffer[j];
j++;
}
tqbs->len=abs(exponent)+digits; // terminate
}
}
else if(exponent>0){
if((digits<18)&&(exponent<16)){
tqbs->chr[1]=qbs_str_buffer[1]; // first digit
j=3; // skip over .
for(i=2;i<=(exponent+1);i++){
tqbs->chr[i]=qbs_str_buffer[j];
j++;
}
if((digits>exponent)&&(digits>(j-1))){
tqbs->chr[exponent+2]='.';
for(i=exponent+3;i<=(digits);i++){
tqbs->chr[i]=qbs_str_buffer[j];
j++;
}
tqbs->len=digits+1;
}
else{
tqbs->len=exponent+2;
}
}
else{
for(i=0;i<=digits;i++){
tqbs->chr[i]=qbs_str_buffer[i];
}
if(tqbs->chr[digits]=='.'){
tqbs->chr[digits]='D';
sprintf((char*)&tqbs->chr[digits+1],"%+03d", exponent);
l=digits+1;
while((tqbs->chr[l])!=0) l++;
tqbs->len=l;
}
else{
tqbs->chr[digits+1]='D';
sprintf((char*)&tqbs->chr[digits+2],"%+03d", exponent);
l=digits+2;
while((tqbs->chr[l])!=0) l++;
tqbs->len=l;
}
}
}
return tqbs;
}
qbs *qbs_str(long double value){
static qbs *tqbs;
tqbs=qbs_new(32,1);
static int32 l, i,j,digits,exponent;
#ifdef QB64_MINGW
__mingw_sprintf((char*)&qbs_str_buffer,"% .17Le", value);
#else
sprintf((char*)&qbs_str_buffer,"% .17Le", value);
#endif
exponent=atoi((char*)&qbs_str_buffer[21]);
digits=19;
while((qbs_str_buffer[digits]=='0')&&(digits>0)) digits--;
tqbs->chr[0]=qbs_str_buffer[0]; // copy sign
if(exponent==0){
for(i=1;i<=(digits);i++){
tqbs->chr[i]=qbs_str_buffer[i];
}
if(tqbs->chr[digits]=='.') // if no digits after . then nip it
tqbs->len=digits; // by zero terminating
else
tqbs->len=digits+1; // terminate
}
else if(exponent<0){
if((digits-exponent)>=22){ // use sci format
for(i=1;i<=digits;i++){
tqbs->chr[i]=qbs_str_buffer[i];
}
if(tqbs->chr[digits]=='.'){
tqbs->chr[digits]='F';
sprintf((char*)&tqbs->chr[digits+1],"%+03d", exponent);
l=digits+1;
while((tqbs->chr[l])!=0) l++;
tqbs->len=l;
}
else{
tqbs->chr[digits+1]='F';
sprintf((char*)&tqbs->chr[digits+2],"%+03d", exponent);
l=digits+2;
while((tqbs->chr[l])!=0) l++;
tqbs->len=l;
}
}
else{
tqbs->chr[1]='.';
for(i=2;i<=abs(exponent);i++){
tqbs->chr[i]='0';
}
tqbs->chr[abs(exponent)+1]=qbs_str_buffer[1]; // first non-zero digit
j=3; // skip decimal point
for(i=abs(exponent)+2;i<(abs(exponent)+digits);i++){
tqbs->chr[i]=qbs_str_buffer[j];
j++;
}
tqbs->len=abs(exponent)+digits; // terminate
}
}
else if(exponent>0){
if((digits<20)&&(exponent<18)){
tqbs->chr[1]=qbs_str_buffer[1]; // first digit
j=3; // skip over .
for(i=2;i<=(exponent+1);i++){
tqbs->chr[i]=qbs_str_buffer[j];
j++;
}
if((digits>exponent)&&(digits>(j-1))){
tqbs->chr[exponent+2]='.';
for(i=exponent+3;i<=(digits);i++){
tqbs->chr[i]=qbs_str_buffer[j];
j++;
}
tqbs->len=digits+1;
}
else{
tqbs->len=exponent+2;
}
}
else{
for(i=0;i<=digits;i++){
tqbs->chr[i]=qbs_str_buffer[i];
}
if(tqbs->chr[digits]=='.'){
tqbs->chr[digits]='F';
sprintf((char*)&tqbs->chr[digits+1],"%+03d", exponent);
l=digits+1;
while((tqbs->chr[l])!=0) l++;
tqbs->len=l;
}
else{
tqbs->chr[digits+1]='F';
sprintf((char*)&tqbs->chr[digits+2],"%+03d", exponent);
l=digits+2;
while((tqbs->chr[l])!=0) l++;
tqbs->len=l;
}
}
}
return tqbs;
}
b = b + ...
Posts: 422
Threads: 27
Joined: Apr 2022
Reputation:
26
@bplus and others
if you want to test how those changes will affect Str$ and the Print of double values then you can apply the change to libqb.cpp and build or rebuild QB64
but you may want to know that it restricts the double output to 15 significant digits, so
1000000000000000# + 1 will print as 1000000000000000 and not 1000000000000001
double has a precision of 53-bits or 15.95 decimal digits, so restricting the output to 15 significant digits helps to eliminate a considerable amount of output like 1.999999999999999 just as an example
but of course if the developers want to include the changes then they can adjust the code to their liking
|