|
Post by Aetzbarr on Jul 8, 2023 21:36:23 GMT
The output of:
print (1d+17)*(1d+17)
is 1d+33. same bug in similar other calculations.
|
|
|
Post by bplus on Jul 9, 2023 2:12:13 GMT
Mantissa is only accurate to 15-16 digits for Double Type
Dim a As Double a = (1D+17) For i = 1 To 17 a = a * (1D+1) Print i; Print Using "###,"; a Next Print Using "###,"; (1D+17) * (1D+17)
|
|
|
Post by Aetzbarr on Jul 9, 2023 6:10:26 GMT
The result displated by QB64 is 10 TIMES SMALLER then the accurate result. Not a little rounding at the 16th digit.
|
|
|
Post by Aetzbarr on Jul 9, 2023 6:46:18 GMT
The output of "print (1d+17)*(1d+17)" should be either 1d+34 or 9.9999999999999d+33 (like QBasic). definitely NOT 1d+33, ehich is 10 times smaller than the true result.
|
|
|
Post by bplus on Jul 9, 2023 13:42:10 GMT
Looks like E works better Print (1E+17) * (1E+17)
|
|
|
Post by Aetzbarr on Jul 9, 2023 15:35:03 GMT
Anyway this is a bug whose source should be found and fixed.
|
|
|
Post by bplus on Jul 9, 2023 16:54:52 GMT
Anyway this is a bug whose source should be found and fixed. Yeah, I'll report it at the other forum.
|
|
|
Post by xrayspex on Jul 9, 2023 20:26:10 GMT
What other forum? How many QB64 forums are there? All the 1s I used to belong to seem to have disappeared. I'm confused which is the right 1.
|
|
|
Post by bplus on Jul 9, 2023 20:32:20 GMT
qb64phoenix.com/forum/index.php Appeared soon after the shutdown of .org and this forum showed up some time later as the "official" one. The development of QB64 has forked off to QB64pe now at v3.8 having a bunch of new things and here v2.1 moving at more conservative pace.
|
|
jack
New Member
Posts: 9
|
Post by jack on Jul 10, 2023 2:18:23 GMT
for anyone that wants better double and _float to string conversion, in internal\c\libqb.cpp replace the functions qbs *qbs_str(double value) and qbs *qbs_str(long double value) with the following 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; }
|
|
jack
New Member
Posts: 9
|
Post by jack on Jul 10, 2023 2:22:42 GMT
if you apply the code above to libqb.cpp then the problem with print (1d+17)*(1d+17) will go away, plus now you can print _Float with a normal Print but apparently the compiler needs to be rebuilt
|
|
|
Post by Aetzbarr on Jul 21, 2023 14:43:40 GMT
Actually there is a simpler way to demonstrate the same bug: just try PRINT 1d34.
|
|
tandt
New Member
Everything of value is defenceless.
Posts: 6
|
Post by tandt on Aug 24, 2023 1:18:07 GMT
Actually there is a simpler way to demonstrate the same bug: just try PRINT 1d34. This is serious. I hope it can be fixed.
|
|
|
Post by bplus on Aug 24, 2023 12:43:55 GMT
Actually there is a simpler way to demonstrate the same bug: just try PRINT 1d34. This is serious. I hope it can be fixed. Nah, this is probably been around for ages. Already we see 2 work arounds mentioned above. I have code that will by pass Scientific notation and display calculations as strings without the exponents as yet another way around.
|
|
jack
New Member
Posts: 9
|
Post by jack on Aug 26, 2023 14:27:47 GMT
Actually there is a simpler way to demonstrate the same bug: just try PRINT 1d34. This is serious. I hope it can be fixed. my post above has the fix
|
|