How can I change the precision of printing with the stl? - c++

I want to print numbers to a file using the stl with the number of decimal places, rather than overall precision.
So, if I do this:
int precision = 16;
std::vector<double> thePoint(3);
thePoint[0] = 86.3671436;
thePoint[1] = -334.8866574;
thePoint[2] = 24.2814;
ofstream file1(tempFileName, ios::trunc);
file1 << std::setprecision(precision)
<< thePoint[0] << "\\"
<< thePoint[1] << "\\"
<< thePoint[2] << "\\";
I'll get numbers like this:
86.36714359999999\-334.8866574\24.28140258789063
What I want is this:
86.37\-334.89\24.28
In other words, truncating at two decimal points. If I set precision to be 4, then I'll get
86.37\-334.9\24.28
ie, the second number is improperly truncated.
I do not want to have to manipulate each number explicitly to get the truncation, especially because I seem to be getting the occasional 9 repeating or 0000000001 or something like that that's left behind.
I'm sure there's something obvious, like using the printf(%.2f) or something like that, but I'm unsure how to mix that with the stl << and ofstream.

Use std::fixed , this should work for you.
file1 << std::fixed << std::setprecision(precision)
<< thePoint[0] << "\\"
<< thePoint[1] << "\\"
<< thePoint[2] << "\\";

Try
file1 << std::setiosflags(ios::fixed) << std::setprecision(precision)
which sets fixed-point format instead of floating-point.
(By the way, this is not STL. It's iostream.)
…Oh! I think Kumar bettered me with std::fixed.

Related

concatenating a Hexadecimal number with zeros

I have written a simple code to convert a fractional number to 24bit (3 bytes, 6 characters) Hexadecimal number.
Lets say if you enter 0.5, it provides the hexadecimal number as 0x400000.
0.1 = 0xccccd
0.001 = 0x20c5
While the answers are correct, What I'd like to do is preserve the 6 character representation, so i'd like 0.1 to be = 0x0ccccd and
0.001 to be = 0x0020c5.
I thought one possible method would be to convert the hexadecimal result to string and then use strlen to check number of digits and then concatenate the result with the appropriate zeros. The problem I have with this method is I'm not sure how to store the hex result in a variable.
I figured even if I convert the Hex number to string and find the number of zeros to concatenate, the program would be a bit clunky. There just might be a simpler way to achieve what I want to do. I just don't know how.
Hoping someone can show me the way forward. The program I wrote is below.
while(true){
float frac_no;
std::cout << "Enter a fractional number(0-1) or press 0 to exit:";
std::cin >> frac_no;
if(!frac_no){
break;
}
const int max_limit_24 = exp2(23); // The maximum value of 0x7FFFFF(1.0)
float inter_hex;
inter_hex = round(max_limit_24*frac_no);
int int_inter_hex = int(inter_hex);
std::cout << std::hex << "0x" << int_inter_hex << "\n" ;
}
#include <iomanip>
int val = 0x20c5;
std::cout << "0x" << std::setw(6) << std::hex << std::setfill('0') << val << '\n';
If you just need it to have the leading 0s on output. If you do want to store it as a string, you can use an std::stringstream instead of std::cout and get the string from it.

How can I get std::stringsteam to line up decimal places on floating point numbers?

In C++, I have some code like this:
float hits = 10.12;
float mins = 2.19;
std::ostringstream ss;
ss.precision(2);
ss << std::fixed << hits << "%\n"
<< std::fixed << mins << "%";
std::cout << ss.str();
Which is giving me this output:
10.12%
2.19%
Whereas, instead I would like the decimal places to align:
10.12%
2.19%
Is there a way to pad with spaces before the decimal to have a fixed width of space for two digits before the decimal place?
Use width to set the column size and then std::right to justify the output.
There are setw() and setprecision() to determine the output-width and the precision for floating-point-values. So you should be able to use it like
ss << setw(8) << hits << "%\n"; ...
Look here for reference.

double and stringstream formatting

double val = 0.1;
std::stringstream ss;
ss << val;
std::string strVal= ss.str();
In the Visual Studio debugger, val has the value 0.10000000000000001 (because 0.1 can't be represented).
When val is converted using stringstream, strVal is equal to "0.1". However, when using boost::lexical_cast, the resulting strVal is "0.10000000000000001".
Another example is the following:
double val = 12.12305000012;
Under visual studio val appears as 12.123050000119999, and using stringstream and default precision (6) it becomes 12.1231. I don't really understand why it is not 12.12305(...).
Is there a default precision, or does stringstream have a particular algorithm to convert a double value which can't be exactly represented?
Thanks.
You can change the floating-point precision of a stringstream as follows:
double num = 2.25149;
std::stringstream ss(stringstream::in | stringstream::out);
ss << std::setprecision(5) << num << endl;
ss << std::setprecision(4) << num << endl;
Output:
2.2515
2.251
Note how the numbers are also rounded when appropriate.
For anyone who gets "error: ‘setprecision’ is not a member of ‘std’" you must #include <iomanip> else setprecision(17) will not work!
There are two issues you have to consider. The first is the precision
parameter, which defaults to 6 (but which you can set to whatever you
like). The second is what this parameter means, and that depends on the
format option you are using: if you are using fixed or scientific
format, then it means the number of digits after the decimal (which in
turn has a different effect on what is usually meant by precision in the
two formats); if you are using the default precision, however (ss.setf(
std::ios_base::fmtflags(), std::ios_base::formatfield ), it means the
number of digits in the output, regardless of whether the output was
actually formatted using scientific or fixed notation. This explains
why your display is 12.1231, for example; you're using both the
default precision and the default formattting.
You might want to try the following with different values (and maybe
different precisions):
std::cout.setf( std::ios_base::fmtflags(), std::ios_base::floatfield );
std::cout << "default: " << value[i] << std::endl;
std::cout.setf( std::ios_base::fixed, std::ios_base::floatfield );
std::cout << "fixed: " << value[i] << std::endl;
std::cout.setf( std::ios_base::scientific, std::ios_base::floatfield );
std::cout << "scientific: " << value[i] << std::endl;
Seeing the actual output will probably be clearer than any detailed description:
default: 0.1
fixed: 0.100000
scientific: 1.000000e-01
The problem occurs at the stream insertion ss << 0.1; rather than at the conversion to string. If you want non-default precision you need to specify this prior to inserting the double:
ss << std::setprecision(17) << val;
On my computer, if I just use setprecision(16) I still get "0.1" rather than "0.10000000000000001". I need a (slightly bogus) precision of 17 to see that final 1.
Addendum
A better demonstration arises with a value of 1.0/3.0. With the default precision you get a string representation of "0.333333". This is not the string equivalent of a double precision 1/3. Using setprecision(16) makes the string "0.3333333333333333"; a precision of 17 yields "0.33333333333333331".

stringstream noshowpoint doesn't work

I'm trying to write 67.5 as 006750 with code below:
float price = 67.5
stringstream symbol;
symbol << setfill('0') << setw(6) << fixed << setprecision(2)
<< noshowpoint << price;
but output is 067.50
You are confused. std::noshowpoint only eliminates the trailing .0 on integer floats, for example 60.0 gets outputted as 60, it doesn't simply remove the point on all numbers.
To get what you want you can do this:
float price = 67.5;
std::stringstream symbol;
symbol << std::setfill('0') << std::setw(6) << int(100 * price);
Looks like you're trying to use noshowpoint to remove the decimal, but if you take a look at the example here you'll see that when pi is printed with noshowpoint, it still retains the decimal probably because you loose your precision without it.
I'd probably just do some string manipulation by hand here, as none of the stringstream options I saw seem to do what you want.

Display a number decimal format instead as an exponential in cout

I calculated a total of floats and I got a number like 509990e-405. I'm assuming this is the short version; how can I cout this as a full number?
cout << NASATotal << endl;
is what I have now.
You can force the output to be not in scientific notation, and to have the sufficient precision to show your small number.
#include <iomanip>
// ...
long double d = 509990e-405L;
std::cout << std::fixed << std::setprecision(410) << d << std::endl;
Output:
0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050999000000
If you really want this is another question.
You can write your own BigNumber class that stores the results as strings. You would have to implement all of your numeric operations and I'm guessing performance will be an issue. But it can be done, no problem -- assuming that is what you want.