RFC: fp printing speedup patch
Jerry Quinn
jlquinn@optonline.net
Fri Nov 14 06:27:00 GMT 2003
Paolo Carlini writes:
> Hi Jerry. I'm just back and still trying to catch up...
>
> Anyway, I have already printed the patch and was hoping to return
> to you tomorrow or at most on monday.
>
> Some things I can tell you immediately:
>
> 1- For something so delicate (it affects the output of *most*
> programs!) we definitely must be *very* careful! You should
> post *many* details about the tests you have done, perhaps
> many actual testcases too, for instance something like a loop
> generating random floats and comparing the output of the
> library to that of plain "C" printfs (using strings, of course
> for that).
Here's the randomizing test I use on the floatconv library. The only
output I get is examples of the following:
mismatch mode e.0
fd.x[0]=0x49e74cea; fd.x[1]=0x3fef807a;
dtoa 1e+00
printf 1e-00
mismatch mode g.0
fd.x[0]=0x9d2eaebf; fd.x[1]=0xbf18ff3f;
dtoa -0.0001
printf -1e-04
Dtoa is the new float library. In both cases, I think printf is
incorrect and a glibc(v2.3.2) bug. Someone with the C standard feel
free to tell me otherwise.
I also extracted a 200k fp testsuite that also passes with flying
colors.
Jerry
#include <sstream>
#include <iostream>
#include <iomanip>
#include <limits>
int main(void)
{
// Can't test 60 since libstd++ clips the precision - but 60 works without that clipping
const int __max_digits = std::numeric_limits<double>::digits10 + 2;
// int ndig = 60;
int ndig = __max_digits;
char buf[25600];
char buf2[25600];
union fpstruct {
double d;
long x[2];
long long y;
} fd;
bool dorand=true;
bool outcpp = false;
bool dosprintf=true;
bool outsprintf=false;
bool doprintf=false;
bool cmpall=true;
for (int i=0; i<5000000; i++) {
// Tends to make lots of extreme numbers. dtoa is slow here. mp
// math can be improved. for double, use long double math if it
// gets fixed.
if (dorand) {
fd.x[0] = mrand48();
fd.x[1] = mrand48();
}
// "Reasonable" numbers are efficient in dtoa. prob more realistic
else
fd.d = i;
if (outcpp)
std::cout << std::setprecision(6) << std::fixed << fd.d << "\n";
std::ostringstream os;
os << std::setprecision(6) << std::fixed << fd.d;
if (dosprintf) sprintf(buf2, "%f",fd.d);
if (outsprintf) std::cout << buf2 << "\n";
if (cmpall && os.str() != buf2) {
printf("mismatch mode f\n");
printf("fd.x[0]=0x%x; fd.x[1]=0x%x;\n", fd.x[0], fd.x[1]);
printf("dtoa %s\n", os.str().c_str());
printf("printf %s\n", buf2);
}
os.str("");
if (outcpp)
std::cout << std::setprecision(0) << std::fixed << fd.d << "\n";
os << std::setprecision(0) << std::fixed << fd.d;
if (dosprintf) sprintf(buf2, "%.0f",fd.d);
if (outsprintf) std::cout << buf2<<"\n";
if (cmpall && os.str() != buf2) {
printf("mismatch mode f.0\n");
printf("fd.x[0]=0x%x; fd.x[1]=0x%x;\n", fd.x[0], fd.x[1]);
printf("dtoa %s\n", os.str().c_str());
printf("printf %s\n", buf2);
}
os.str("");
if (outcpp)
std::cout << std::setprecision(6) << std::scientific << fd.d << "\n";
os << std::setprecision(6) << std::scientific << fd.d;
if (dosprintf) sprintf(buf2, "%e",fd.d);
if (outsprintf) std::cout << buf2 << "\n";
if (cmpall && os.str() != buf2) {
printf("mismatch mode e\n");
printf("fd.x[0]=0x%x; fd.x[1]=0x%x;\n", fd.x[0], fd.x[1]);
printf("dtoa %s\n", os.str().c_str());
printf("printf %s\n", buf2);
}
os.str("");
if (outcpp)
std::cout << std::scientific << std::setprecision(0) << fd.d << "\n";
os << std::scientific << std::setprecision(0) << fd.d;
if (dosprintf) sprintf(buf2, "%.0e",fd.d);
if (outsprintf) std::cout << buf2 << "\n";
if (cmpall && os.str() != buf2) {
printf("mismatch mode e.0\n");
printf("fd.x[0]=0x%x; fd.x[1]=0x%x;\n", fd.x[0], fd.x[1]);
printf("dtoa %s\n", os.str().c_str());
printf("printf %s\n", buf2);
}
os.str("");
if (outcpp)
std::cout << std::setprecision(ndig) << std::scientific << fd.d << "\n";
os << std::setprecision(ndig) << std::scientific << fd.d;
if (dosprintf) sprintf(buf2, "%.*e",ndig,fd.d);
if (outsprintf) std::cout << buf2 << "\n";
if (cmpall && os.str() != buf2) {
printf("mismatch mode e.60\n");
printf("fd.x[0]=0x%x; fd.x[1]=0x%x;\n", fd.x[0], fd.x[1]);
printf("dtoa %s\n", os.str().c_str());
printf("printf %s\n", buf2);
}
os.str("");
if (outcpp) {
std::cout.unsetf(std::ios_base::scientific);
std::cout << std::setprecision(6) << fd.d << "\n";
}
os.unsetf(std::ios_base::scientific);
os << std::setprecision(6) << fd.d;
if (dosprintf) sprintf(buf2, "%g",fd.d);
if (outsprintf) std::cout << buf2 << "\n";
if (cmpall && os.str() != buf2) {
printf("mismatch mode g\n");
printf("fd.x[0]=0x%x; fd.x[1]=0x%x;\n", fd.x[0], fd.x[1]);
printf("dtoa %s\n", os.str().c_str());
printf("printf %s\n", buf2);
}
os.str("");
if (outcpp)
std::cout << std::setprecision(0) << fd.d << "\n";
os << std::setprecision(0) << fd.d;
if (dosprintf) sprintf(buf2, "%.0g",fd.d);
if (outsprintf) std::cout << buf2 << "\n";
if (cmpall && os.str() != buf2) {
printf("mismatch mode g.0\n");
printf("fd.x[0]=0x%x; fd.x[1]=0x%x;\n", fd.x[0], fd.x[1]);
printf("dtoa %s\n", os.str().c_str());
printf("printf %s\n", buf2);
}
os.str("");
if (outcpp)
std::cout << std::setprecision(ndig) << fd.d << "\n";
os << std::setprecision(ndig) << fd.d;
if (dosprintf) sprintf(buf2, "%.*g",ndig, fd.d);
if (outsprintf) std::cout << buf2 << "\n";
if (cmpall && os.str() != buf2) {
printf("mismatch mode g.60\n");
printf("fd.x[0]=0x%x; fd.x[1]=0x%x;\n", fd.x[0], fd.x[1]);
printf("dtoa %s\n", os.str().c_str());
printf("printf %s\n", buf2);
}
if (outcpp || outsprintf) puts("-----");
}
}
More information about the Libstdc++
mailing list