qbs_str my mod
#9
ok, for completeness I will make one last post since no-one seems to be interested
the following version sets the digits to 16 but it converts the double in two buffers, one to 15 digits the other to 16 digits
it counts the trailing 0's of the two buffers and if the difference between them is greater than 1 and also the exponents remain the same then use the 15-digit buffer
qbs_str code
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; // zero 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; // zero 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; // zero 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; // zero 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;
}
QB64 sample
Code: (Select All)
Dim As Double x
For x = -1 To 1 Step .1#
    Print x
Next
Print "-----------------"
For x = 1 To 10
    Print x / 9#
Next
output
Quote:-1
-.9
-.8
-.7
-.6
-.5
-.4
-.3
-.2
-.1
-1.387778780781446D-16
9.999999999999987D-02
.2
.3
.4
.5
.6
.7
.8
.9
.9999999999999998
-----------------
.1111111111111111
.2222222222222222
.3333333333333333
.4444444444444444
.5555555555555556
.6666666666666666
.7777777777777778
.8888888888888888
1
1.111111111111111
I realize that the output differs from that of QB-4.5 but this is the best that I care to do
Reply


Messages In This Thread
qbs_str my mod - by Jack - 04-19-2022, 01:18 AM
RE: qbs_str my mod - by Pete - 04-19-2022, 02:16 AM
RE: qbs_str my mod - by Jack - 04-19-2022, 02:36 AM
RE: qbs_str my mod - by admin - 04-19-2022, 04:03 AM
RE: qbs_str my mod - by Jack - 04-19-2022, 03:57 PM
RE: qbs_str my mod - by Jack - 04-19-2022, 06:57 PM
RE: qbs_str my mod - by Jack - 04-19-2022, 10:21 PM
RE: qbs_str my mod - by Jack - 04-20-2022, 02:34 AM
RE: qbs_str my mod - by Jack - 04-20-2022, 03:08 PM
RE: qbs_str my mod - by admin - 04-20-2022, 03:22 PM



Users browsing this thread: 4 Guest(s)