would you guys test the following code for logic errors?
the goal here is to replace the current double to string conversion that's faulty in QB64
I must have concluded at least a dozen times that all was ok only to discover a bug
[edit1]
restricted the maximum digits to 15, with 16 digits there are too many cases that suffer from floating-point inaccuracies, like trying to print 1d-21 would give 9.999999999999999d-22
[edit2]
added a test program, let me know what you think
[edit3]
added another test
the goal here is to replace the current double to string conversion that's faulty in QB64
I must have concluded at least a dozen times that all was ok only to discover a bug
[edit1]
restricted the maximum digits to 15, with 16 digits there are too many cases that suffer from floating-point inaccuracies, like trying to print 1d-21 would give 9.999999999999999d-22
[edit2]
added a test program, let me know what you think
[edit3]
added another test
Code: (Select All)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#define QB64_MINGW
int str(double value){
char buf[64];
char buf2[64];
int32_t i, j, lsd, exp;
//double value=.000000000000000000001; //3.141592653589e3; //3.141592653589793e-10;
#ifdef QB64_MINGW
__mingw_sprintf((char*)&buf,"% .14Le",(long double) value);
#else
sprintf((char*)&buf,"% .14Le",(long double) value);
#endif
exp=atoi(&buf[18]);
lsd=16;
while((buf[lsd]=='0')&&(lsd>0)) lsd--;
buf2[0]=buf[0]; // copy sign
if(exp==0){
for(i=1;i<=(lsd);i++){
buf2[i]=buf[i];
}
if(buf2[lsd]=='.') // if no digits after . then nip it
buf2[lsd]=0; // by zero terminating
else
buf2[lsd+1]=0; // zero terminate
}
else if(exp<0){
if((lsd-exp)>=19){ // use sci format
for(i=1;i<=lsd;i++){
buf2[i]=buf[i];
}
if(buf2[lsd]=='.'){
buf2[lsd]='D';
sprintf(&buf2[lsd+1],"%+03d", exp);
}
else{
buf2[lsd+1]='D';
sprintf(&buf2[lsd+2],"%+03d", exp);
}
}
else{
buf2[1]='.';
for(i=2;i<=abs(exp);i++){
buf2[i]='0';
}
buf2[abs(exp)+1]=buf[1]; // first non-zero digit
j=3; // skip decimal point
for(i=abs(exp)+2;i<(abs(exp)+lsd);i++){
buf2[i]=buf[j];
j++;
}
buf2[abs(exp)+lsd]=0; // zero terminate
}
}
else if(exp>0){
if((lsd<17)&&(exp<15)){
buf2[1]=buf[1]; // first digit
j=3; // skip over .
for(i=2;i<=(exp+1);i++){
buf2[i]=buf[j];
j++;
}
if((lsd>exp)&&(lsd>(j-1))){
buf2[exp+2]='.';
for(i=exp+3;i<=(lsd);i++){
buf2[i]=buf[j];
j++;
}
buf2[lsd+1]=0;
}
else{
buf2[exp+2]=0;
}
}
else{
for(i=0;i<=lsd;i++){
buf2[i]=buf[i];
}
if(buf2[lsd]=='.'){
buf2[lsd]='D';
sprintf(&buf2[lsd+1],"%+03d", exp);
}
else{
buf2[lsd+1]='D';
sprintf(&buf2[lsd+2],"%+03d", exp);
}
}
}
printf("%s", buf2);
return 0;
}
int main(void){
time_t t;
double x;
char* ptr;
char strx[50]="3141592653589793";
char c;
int i, j, k;
srand((unsigned) time(&t));
for(i=1;i<3;i++){
for(j=1;j<15;j++){
k=rand() %j;
c=strx[k];
strx[k]='.';
x=strtod(strx,&ptr);
str(x); printf("% .14e %s\n",x,strx);
strx[k]=c;
}
}
printf("%s\n","====================================================");
char stry[50]="3.141592653589793e";
for(i=1;i<3;i++){
for(j=1;j<15;j++){
k=rand() %j;
k=k * (13 - (-13)) + (-13);
sprintf(&stry[18],"%d", k);
x=strtod(stry,&ptr);
str(x); printf("% .14e %s\n",x,stry);
}
}
printf("%s\n","====================================================");
strx[0]='1';
for(j=1;j<41;j++){
for(i=1;i<=j;i++){
strx[i]='0';
}
strx[i]=0;
x=strtod(strx,&ptr);
str(x); printf("% .14e %s\n",x,strx);
}
printf("%s\n","====================================================");
strx[0]='.';
for(j=1;j<41;j++){
for(i=1;i<=j;i++){
strx[i]='0';
}
strx[i]='1';
strx[i+1]=0;
x=strtod(strx,&ptr);
str(x); printf("% .14e %s\n",x,strx);
}
return 0;
}