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
QB64 sample
output
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;
}
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
Quote:-1I realize that the output differs from that of QB-4.5 but this is the best that I care to do
-.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