|
-
August 14th, 2002, 05:16 AM
#1
Truncated floating point with C++ streams
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:
Code:
#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;
}
You're gonna go blind staring into that box all day.
-
August 14th, 2002, 08:19 AM
#2
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,
ZDF
What is good is twice as good if it's simple.
"Make it simple" is a complex task.
-
August 14th, 2002, 09:55 AM
#3
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:
Code:
#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;
}
You're gonna go blind staring into that box all day.
-
August 15th, 2002, 07:26 AM
#4
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;
-
August 15th, 2002, 11:10 AM
#5
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.
Code:
#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;
}
Ce n'est que pour vous dire ce que je vous dis.
-
August 15th, 2002, 12:01 PM
#6
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:
Code:
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,
Last edited by zdf; August 15th, 2002 at 12:07 PM.
ZDF
What is good is twice as good if it's simple.
"Make it simple" is a complex task.
-
August 15th, 2002, 12:43 PM
#7
Sorry, I misinterpreted the OP. Would this solution be acceptible?
Code:
#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;
}
Last edited by Alexey B; August 15th, 2002 at 12:46 PM.
Ce n'est que pour vous dire ce que je vous dis.
-
August 16th, 2002, 02:48 AM
#8
Nine lives...
Nice solution!
Thanks to everyone.
The solution also works in the digit range 15 where the actual application will use it.
Code:
#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;
}
You're gonna go blind staring into that box all day.
-
August 16th, 2002, 04:00 AM
#9
Ooopppsss!
Good morning Chris!
I misinterpreted your question too. I thought you do not want to rely on math. 
Good luck!
ZDF
What is good is twice as good if it's simple.
"Make it simple" is a complex task.
-
August 16th, 2002, 06:12 AM
#10
streamlined
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.
You're gonna go blind staring into that box all day.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|