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