Using stringstream precision to format floats but discarding zero-padding - c++

I'm trying to set precision (i.e. number of decimal places) of floats and long doubles to 10, but i don't want them zero padded. I.e.,
123456.789123456789 should give 123456.7891234568, but
123456 should not give 123456.0000000000, but rather 123456
So far i've narrowed it down to:
long double myNumber;
string myString;
ostringstream myStream;
myStream.setf(ios::fixed,ios::floatfield);
myStream.precision(10);
myStream << myNumber;
myString = myStream.str();
I've also tried fiddling with setfill(' ') and std::ws but can't really get the hang of it.
Any suggestions?

Don't use ios::fixed for ios::floatfield. That's what causes the padding. Simply use setprecision.

Related

Why doesn't this function print all the char array as it takes it?

i was trying to convert from a char array to integers and the atoi function is working properly except when i put a zero in the first index...it didn't print it
#include<iostream>
using namespace std;
int main()
{
char arr[]= "0150234";
int num;
num=atoi(arr);
cout << num;
return 0;
}
I expect the output of 0150234 but the actual output is 150234
I think inside the atoi function you have typecasted the string to integer because of which the 0 gets removed. You can never get a 0 printed before a number since it doesn't make sense.
000001 will always be represented as 1.
I hope this clears your doubt.
Binary number representations (such as int) do not store leading 0s because there is an infinite number of them. Rather they store a fixed number of bits which may have some leading 0 bits.
You can still print the leading 0s if necessary:
std::cout << std::setw(4) << std::setfill('0') << 1 << '\n';
Output:
0001
You're confusing two ideas:
Numbers: These are abstract things. They're quantities. Your computer stores the number in a manner that you should not care about (though it's probably binary).
Representations: These are ways we display numbers to humans, like "150234", or "0x24ADA", or "one hundred and fifty thousand, two hundred and thirty four". You pick a representation when you convert to a string. When streaming to std::cout a representation is picked for you by default, but you can choose your own representation using I/O manipulators, as Maxim shows.
The variable num is a number, not a representation of a number. It does not contain the information «display this as "0150234"». That's what arr provides, because it is a string, containing a representation of a number. So, if that leading zero in the original representation is important to you, when you print num, you have to reproduce that representation yourself.
By the way…
Usually, in the programming world, and particularly in C-like source code:
When we see a string like "150234" we assume that it is the decimal (base-10) representation of a number;
When we see a string like "0x24ADA" (with a leading 0x) we assume that it is the hexadecimal (base-16) representation of a number;
When we see a string like "0150234" (with a leading 0) we assume that it is the octal (base-8) representation of a number.
So, if you do add a leading zero, you may confuse your users.
FYI the conventional base-8 representation of your number is "0445332".

c++ How to extract numbers from a string that has backslash?

I am trying to extract numbers from a string.
I would like to save each number to a separate double variable.
I currently tried using a simple stringstream like this.
std::string line = "100.2456426246\200.2624362436\300.136213477347";
std::stringstream stream(line);
stream.precision(20);
double a,b,c;
stream >> a >> b >> c;
Not only is the precision wrong(only prints out 6 digits), it only extracts the first number a(100.245), and b and c is null. I suspect it is due to backslash, but I'm not exactly sure.
What is the best way to read the string which contains backslash between each number and store the whole number with correct precision?
You could use getline with a delimiter to split a string into a vector of elements and atof to extract floats along these lines
vector<string> elems;
stringstream stream(line);
string item;
while (getline(stream, item, "\\")) {
elems.push_back(item);
}
vector<float> val(elems.size());
...
val[i]=atof(elems[i].c_str())
Precision here is more of a matter of presentation, which you can customize with the help of setprecision. For example,
#include <iomanip>
...
cerr << setprecision(6) << val[i] << endl;
will output the truncation to six significant digits.
Another matter is making sure that all digits up to the last one are stored. To make sure that all digits are stored, simply the size of your defined float must be sufficiently large to contain your data, and atof may need to be replaced by an appropriate parser if float should be replaced by double or something else.

use fixed precision without trailing zeros

I'm using setPrecision and fixed so I can set the precision AFTER the decimal point,
but I don't want to get something like this: 5.00000.
how can I take off the trailing zeros in an elegent way?
any specific way or should I perform string manipulations?
os << setprecision(5) << fixed << value;
Short Answer: Don't use fixed and instead set precision to whatever number you want + number of digits before decimal place.

Hexadecimal in String to Hexadecimal in Integer

I want to know how to convert something like string x = "1f" to int y = 0x1f, every topic I found was solved by turning it to simply the integer value of it (31) or turning the string to a hexadecimal equivalent "Hello" > 48656C6C6F
std::stringstream Strm;
std::string Stng = "1f";
Strm << Stng;
int Hexa;
Strm >> std::hex >> Hexa;
cout << Hexa;
This closest I could get to it (but turned out it just converts it to integer)
EDIT: I guess my problem was I didn't know it must be stored as an integer and can be only shown as hexadecimal if i add std::hex after cout, that was stupid sorry
Integers don't carry labels saying 'I'm a decimal integer' or 'I'm a hexadecimal integer'. All integers are the same. So if you have found some code that converts a hexadecimal string to an integer then that is the code you should use.
Once you have your integer you can then choose to print it out in hexadecimal if you want. You do that with hex
int hexa = ...;
cout << hex << hexa; // prints an int in hexadecimal form
One quite fast solutions is using boost::lexical cast. You can find everything here http://www.boost.org/doc/libs/1_53_0/doc/html/boost_lexical_cast.html
You have two choices:
std::strtol
std::stoi
The last will throw an exception if the input string is not a proper hexadecimal number.
And remember, in the computer all integers are stored in binary, hexadecimal is just a presentation. For example, the ASCII character 'a' is the same as decimal number 97 and the same as octal number 141 and the same as hexadecimal number 61 and the same as binary number (which it is ultimately is stored as in memory) 01100001.

Maximum Width of a Printed Double in C++

I was wondering, how long in number of characters would the longest a double printed using fprintf be? My guess is wrong.
Thanks in advance.
Twelve would be a bit of an underestimate. On my machine, the following results in a 317 character long string:
#include <limits>
#include <cstdio>
#include <cstring>
int main()
{
double d = -std::numeric_limits<double>::max();
char str[2048] = "";
std::sprintf(str, "%f", d);
std::size_t length = std::strlen(str);
}
Using %e results in a 14 character long string.
Who knows. The Standard doesn't say how many digits of precision a double provides other than saying it (3.9.1.8) "provides at least as much precision as float," so you don't really know how many characters you'll need to sprintf an arbitrary value. Even if you did know how many digits your implementation provided, there's still the question of exponential formatting, etc.
But there's a MUCH bigger question here. Why the heck would you care? I'm guessing it's because you're trying to write something like this:
double d = ...;
int MAGIC_NUMBER = ...;
char buffer[MAGIC_NUMBER];
sprintf(buffer, "%f", d);
This is a bad way to do this, precisely because you don't know how big MAGIC_NUMBER should be. You can pick something that should be big enough, like 14 or 128k, but then the number you picked is arbitrary, not based on anything but a guess that it will be big enough. Numbers like MAGIC_NUMBER are, not suprisingly, called Magic Numbers. Stay away from them. They will make you cry one day.
Instead, there's a lot of ways to do this string formatting without having to care about buffer sizes, digits of precision, etc, that let you just get on with the buisness of programming. Streams is one:
#include <sstream>
double d = ...;
stringstream ss;
ss << d;
string s = ss.str();
cout << s;
...Boost.Format is another:
#include <boost\format\format.hpp>
double d = ... ;
string s = (boost::format("%1%") % d).str();
cout << s;
Its defined in limits:
std::cout << std::numeric_limits<double>::digits << "\n";
std::cout << std::numeric_limits<double>::digits10 << "\n";
Definition:
digits: number of digits (in radix base) in the mantissa
Equivalent to FLT_MANT_DIG, DBL_MANT_DIG or LDBL_MANT_DIG.
digits10: Number of digits (in decimal base) that can be represented without change.
Equivalent to FLT_DIG, DBL_DIG or LDBL_DIG for floating types.
See: http://www.cplusplus.com/reference/std/limits/numeric_limits/
Of course when you print stuff to a stream you can use the stream manipulators to limit the size of the output.
you can decide it by yourself..
double a=1.1111111111111111111111111111111111111111111111111;
printf("%1.15lf\n", a);
return 0;
./a.out
1.111111111111111
you can print more than 12 characters..
If your machine uses IEEE754 doubles (which is fairly widespread now), then the binary precision is 53 bits; The decimal equivalent is approximately 15.95 (calculated via logarithmic conversion), so you can usually rely on 15 decimal digits of precision.
Consult Double precision floating-point format for a brief discussion.
For a much more in-depth study, the canonical paper is What Every Computer Scientist Should Know About Floating-Point Arithmetic. It gets cited here whenever binary floating point discussions pop up, and is worth a weekend of careful reading.