Click to See Complete Forum and Search --> : Truncated floating point with C++ streams


dude_1967
August 14th, 2002, 05:16 AM
Hello,

Can anyone please tell me the appropriate flag combination for formating truncated floating point values using C++ streams. I do not want any rounding.

Thanks 1*10^6 (thanks a million).

Chris.

Code example with questions within the comments:



#include <iostream>
#include <iomanip>
using namespace std;

int main(int argc, char* argv[])
{
// Have nine nines.
double d = 0.999999999;

// Want eight nines but don't get it.
// How do I get the truncation?
// Is it possible using streams?
cout << std::setprecision(8) << std::fixed << d << endl;

return 1;
}



:)

zdf
August 14th, 2002, 08:19 AM
I do not think you’ll manage to do this in one line of code. Streams ultimately are using sprintf (at least the library I have) to convert the data: >> is not smarter than sprintf.

How about truncating a string that contains your converted number (with a large enough precision… say 80)?

Regards,

dude_1967
August 14th, 2002, 09:55 AM
Hi zdf,

Thank you.

Indeed it's no problem to use ::sprintf(...) and related functions. Or some combination of stringstreams and strings (see sample below).

But it must be possible to get a truncated floating point value from a stream using a single line of code. I would really like to do this kind of thing using a single line.

Does anyone know how to set a stream's flags appropriately to truncate double without rounding?

Thanks. Chris.

UGLY sample:



#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;

int main(int argc, char* argv[])
{
stringstream ss;
string str;

// Have nine nines.
double d = 0.999999999;

ss << std::fixed << std::setprecision(80) << d << endl;
ss >> str;

str = str.substr(str.find('.'), 9);

// Want eight nines but don't get it.
cout << str << endl;

return 1;
}



:)

Plastelin
August 15th, 2002, 07:26 AM
May you have trabble of default values?
as I know compiler has default value 'int' and 'float' and if there is some number with uncnown type it convert it to 'int' or 'float'. So may be for initialization you need to do this:
double a = 1.0;
a = a - 1.0e-5;

Alexey B
August 15th, 2002, 11:10 AM
The L suffix will tell the compiler that the value is of the type double. Also, make the precision 9 for this example instead of 8.#include <iostream>
#include <iomanip>
using namespace std;

int main(int argc, char* argv[])
{
double d = 0.999999999L;
cout << std::setprecision(9) << d << endl;

return 0;
}

zdf
August 15th, 2002, 12:01 PM
Originally posted by Alexey B
Also, make the precision 9 for this example instead of 8.

Hi Alexey B!

What Chris needs, is to display the truncated value (9 digits, truncated to 8). Something like:

double d = double( int( .999 * 100 ) ) / 100. ;

::sprintf as well as streams is rounding to the nearest value; i.e.:
.996 is displayed 1 if the precison is 2.
.994 is displayed .99 if the precision is 2.

To my shame I did not manage to find the "one line" solution.

Regards,

Alexey B
August 15th, 2002, 12:43 PM
Sorry, I misinterpreted the OP. Would this solution be acceptible?#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;

int main(int argc, char* argv[])
{
double d = 0.999999999L;
cout << std::setprecision(8) << floor(d * 1e8L) / 1e8L << endl;
return 0;
}

dude_1967
August 16th, 2002, 02:48 AM
Nice solution!

Thanks to everyone.

The solution also works in the digit range 15 where the actual application will use it.



#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;

int main(int argc, char* argv[])
{
// 16 nines
double d = 0.9999999999999999L;

// Truncate to 15 nines
cout << std::setprecision(15) << floor(d * 1e15L) / 1e15L << endl;

return 0;
}



:)

zdf
August 16th, 2002, 04:00 AM
Good morning Chris!

I misinterpreted your question too. I thought you do not want to rely on math. :D

Good luck!

dude_1967
August 16th, 2002, 06:12 AM
zdf,

Indeed I originally did not want to rely on math or division or anything other than pure streams. However, I really couldn't find the right stream flags for this particular task. I'll either take the solution with floor or read in one extra digit and truncate it by hand.

I'm not sure if the single-line, pure-stream solution exists.

Again, thanks.
Chris.

:)