QB64 Phoenix Edition
D notation bug - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: Chatting and Socializing (https://qb64phoenix.com/forum/forumdisplay.php?fid=11)
+--- Forum: General Discussion (https://qb64phoenix.com/forum/forumdisplay.php?fid=2)
+---- Forum: GitHub Discussion (https://qb64phoenix.com/forum/forumdisplay.php?fid=42)
+---- Thread: D notation bug (/showthread.php?tid=1834)

Pages: 1 2


RE: D notation bug - bplus - 07-10-2023

(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!


RE: D notation bug - mnrvovrfc - 07-14-2023

(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. Smile

[Image: dosbox-qb45-one-d-err.png]


RE: D notation bug - bplus - 08-26-2023

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;
}



RE: D notation bug - Jack - 08-26-2023

@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