Display a number decimal format instead as an exponential in cout - c++

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.

Related

How to cout a float/double with dynamic precision? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
float a = 3.14159;
double b = 3.14159;
cout.precision(6);
cout << a << endl; //3.14159
cout << b << endl; //3.14159
cout.precision(10);
cout << a << endl; //3.141590118
cout << b << endl; //3.14159
cout.precision(20);
cout << a << endl; //3.141590118408203125
cout << b << endl; //3.1415899999999998826
return 0;
}
Can anyone explain the difference between float and double?
How do we print float/double with dynamic precision?
Assuming I have your definition of dynamic correct something like this should work:
void print(float toPrint, int precision)
{
cout.precision(precision);
cout << toPrint <<endl;
}
cout.precision only changes the precision of the printing, it doesn't actually affect how precise the numbers are. If you print with more digits than your numbers have precision, you will get inaccurate digits.
Of course, cout.precision also only changes the maximum precision of the printing. To force it to print trailing zeros, do something like this:
void print(float toPrint, int precision)
{
cout.precision(precision);
cout << fixed;
cout << toPrint <<endl;
}
The difference between a float and a double is that a double is approximately twice as precise as a float. In general, a float has something like 7 or 8 digits of precision, and a double has 15 or 16 digits of precision.
If I'm reading your question correctly you are wondering why both floats and doubles lose precision after you adjust cout.precision.
This occurs because floating point numbers are stored in binary differently than normal whole numbers. A common example of why this matters is that the number 0.6 is stored in binary as 0011111100101.... This, like 0.6666666... in decimal, is an infinitely long number. Thus, your computer needs to decide at what point it should round/approximate the value. When you declare and initialize your floating point numbers a and b, the computer knows that it does not need to cram any value other than 3.14159 into the variable. However, when you then change cout.precision, the computer thinks it needs to round the floating point at a later location. Furthermore, floats are only 16 bits so it will almost always be less precise than the double, which is 32 bits. See here for their ranges.
Obviously to get the correct precision you shouldn't adjust cout.precision to be greater than the number of digits of your variable. However if you want to adjust the precision and just print out a bunch of zeroes after the end of your initial variable value, just use cout << fixed << setprecision(number). See below:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
float a = 3.14159;
double b = 3.14159;
cout.precision(6);
cout << a << endl; //3.14159
cout << b << endl; //3.14159
cout << fixed << setprecision(10);
cout << a << endl; //3.141590118
cout << b << endl; //3.141590000
return 0;
}
Edit: Another option is to use limits.
It doesn't make sense to have a "dynamic precision" where all digits different from 0 are displayed. That mode would have issues with fractional numbers that have infinite decimal digits, like the result of 1.0 / 3.
The best you can do is to set the maximum precision you are willing to see with precision, just like in your example.

How to display multiple leading zeros for floating point values in C++? [duplicate]

This question already has answers here:
How can I pad an int with leading zeros when using cout << operator? [duplicate]
(7 answers)
Closed 7 years ago.
In a C++ program, I want to display a column of floating point values so that the sign, digits, and decimal point all line up. Multiple leading zeros should pad the whole number part of each value, when necessary. For example:
A column of floating point values:
+000.0012
-000.0123
+000.1235
-001.2346
+012.3457
-123.4568
I had an elaborately commented test program that demonstrated the problem. But, as I was editing this post, I found the answer I need here:
- Extra leading zeros when printing float using printf?
The essential problem was that I was using a format code of "%+04.4f" when I should use "%+09.4f", because the total field width I want is 9:
1 for the sign
3 for the whole digits
1 for the decimal point
4 for the fractional digits
I do not have enough reputation points to comment on that post, so thank you from here, #AndiDog.
I still do not know how to get multiple leading zeros using just stream formatting flags. But that is a battle for another day. I will stick with a mixture of printf and stream for now.
A couple of comments have mentioned std::setfill('0') and std::setw. While these are necessary, they're not sufficient to the task. For example, this code:
std::cout << std::setfill('0') << std::setw(7) << std::showpos << 0.012;
will produce: 0+0.012 as its output. This is obviously not quite what we wanted.
We need to add the std::internal flag to tell the stream to insert "internal padding" -- i.e., the padding should be inserted between the sign and the rest of the number, so code like this:
std::cout << std::setfill('0') << std::setw(7) << std::internal << std::showpos << 0.012;
...produces the output we want: +00.012.
Also note that the padding character is "sticky", so if you alternate between using std::setw with numeric and non-numeric types, you'll probably need/want to change it each time. Otherwise, something like std::cout << setw(12) << name; will produce results like: 0000000Jerry, which is rarely desired either.
To assure that we always get the same number of places after the decimal point, we also need to set the std::fixed flag, and specify the number of places with std::setprecision, such as:
#include <iostream>
#include <iomanip>
#include <vector>
int main() {
std::vector<double> values { 0.1234, 1.234, 1.5555 };
for (auto d : values)
std::cout << std::internal << std::showpos << std::setw(9)
<< std::setprecision(3) << std::setfill('0') << d << "\n";
}
Which produces the output I believe is desired:
+0000.123
+0001.234
+0001.556
There is one circumstance under which you won't get aligned results this way though: if you have a number too large to fit into the field provided, all the places before the decimal point will still be printed. For example, if we added 1e10 to the list of numbers to be printed by the preceding code, it would be printed out as: +10000000000.000, which obviously won't align with the rest.
The obvious way to deal with that would be to just put up with it, and if it arises often enough to care about, increase the field size to accommodate the larger numbers.
Another possibility would be to use fixed notation only the number is below a certain threshold, and switch to (for example) scientific notation for larger numbers.
At least in my experience, code like this tends to be used primarily for financial data, in which case the latter option usually isn't acceptable though.
To show the positive sign, you use std::showpos.
To show the leading zeros, you use std::setw(n) and std::setfill('0').
To show the digits after zero, you use std::setprecision(m).
To show the zeros between the + sign and the first digit, you use std::internal.
To keep the digit at a fixed position, you use std::fixed.
#include <iostream> // std::cout, std::fixed
#include <iomanip> // std::setprecision
int main () {
double f =1.234;
double g =-12.234;
std::cout << std::showpos<< std::internal << std::fixed << std::setprecision(4)<<std::setw(9) <<std::setfill('0') << f << '\n';
std::cout <<std::setw(9)<< std::setfill('0') <<g<<"\n"; //repeat these for a new number
return 0;
}
//output:
//+001.2340
//-012.2340
The only way I now how to do this is to display the sign first and then set the fill, width and precision after and display the positive value as you have already displayed the sign. You also need to set the format flag to ios::fixed
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
float x[] = { 000.0012, .0123, .1235, 1.2346, 12.3457, 123.4568 };
cout.setf(ios::fixed);
for (int i = 0; i < 6; i++)
cout << (x[i] > 0 ? '+' : '-') << setfill('0') << setw(8) << setprecision(4) << abs(x[i]) << endl;
return 0;
}
Displays
+000.0012
-000.0123
+000.1235
-001.2346
+012.3457
-123.4568

C++ decimal arithmetic libraries

I'm fairly new to adding additional libraries to Visual Studio (2013) as well as the idea that floats and doubles are usually not accurate enough when dealing with certain things like money. I originally thought that BOOST::Multiprecision cpp_dec_float would solve this problem but as I tested it I noticed some unusually things and realized that I could be wrong. for example,
cpp_dec_float_50 decimal = 0.45;
double dbl = 0.45; //for comparison
cout << fixed << setprecision(50) << "boost: " << decimal << endl;
cout << "double: " << dbl << endl;
would give results like this
boost: 0.45000000000000001110223024625156540423631668090820
double: 0.45000000000000001000000000000000000000000000000000
instead of what I expected (0.45000000000000000000000000000000000000000000000000).
is this not going to be much more accurate than just using floats or doubles? If not, I'm assuming the boost library I just linked to my VS2013 has an arbitrary integer type, would this be acceptable? the only thing I don't like about using integers for such a thing is that I'd probably have to convert interest rates into integers before multiplying it with currency which would likely result in a very, very large number which may or may not cause performance issues.
(assuming BOOST isn't what I need) what are your thoughts on Intel's Decimal Floating-Point Library? I couldn't get it to work (yet) so I'm wondering if it is worth the effort. Are there any other similar libraries worth checking out?
So, you're assigning a number (that is already in floating point) to your decimal variable. So the error that you are concerned about has already been introduced.
Instead, let's assign it with a string containing the correct number:
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
using namespace std;
using boost::multiprecision::cpp_dec_float_50;
int main() {
cpp_dec_float_50 decimal("0.45");
double dbl = 0.45; //for comparison
cout << fixed << setprecision(50) << "boost: " << decimal << endl;
cout << "double: " << dbl << endl;
}
Which outputs:
boost: 0.45000000000000000000000000000000000000000000000000
double: 0.45000000000000001110223024625156540423631668090820
Use Python:
import decimal
d = decimal.Decimal("0.45")
print(d)
outputs 0.45.

C++ Float Truncation & set precision logic error

I looked for a while and couldn't find an answer on here, but it seems to be a kind of weird question. I'm working with the fstream library in C++. What I'm trying to do is take data from an input file, assign it variables, and output this to both the screen and the output file. This is all for a project i'm working on that calculates the monthly payment of the car loan, which is why the variables are named the way they are.
My data file looks like this:
105670.00 12345.00 0.057 4
and essentially what is happening is I am losing everything after the decimal of the first two numbers (regardless of what i put as the decimal), but it doesn't happen to the 3rd number. additionally, when i try to setprecision(2) of the first two numbers i get a strange logic error, which i will show after my code.
my code looks like this:
#include<fstream>
#include<iomanip>
#include<iostream>
using namespace std;
int main ()
{
ifstream din; // These are my input and output files
ofstream dout;
float purchasePrice; // The first number of the input file.
float downPayment; // Second number.
float annualInterest; // Third number.
float numYears; // Last number.
// declaring the input/output files code here
din >> purchasePrice >> downPayment >> annualInterest >> numYears;
cout << purchasePrice << endl;
cout << downPayment << endl;
cout << annualInterest << endl;
cout << setprecision(2) << purchasePrice << endl;
cout << setprecision(2) << downPayment << endl;
cout << setprecison(2) << annualInterest << endl;
}
and here is my output:
105670
12345
0.057
1.1e+005
1.2e+004
0.057
I want my output to be:
105670.00
12345.00
0.057
105670.00
12345.00
0.05
Additionally, when performing any calculations, the numbers act as if they still have everything after the decimal. My question is, why are only some of the floats truncating, and why does setprecision() not work the way it is expected in this case?
Any responses are greatly appreciated, I'm sorry its such a lengthy explanation.
You also need to set the fmtflags to fixed:
std::cout << std::fixed << std::setprecision(2) << purchasePrice << "\n";
Without specifying scientific or fixed, the output mechanisms will use whatever scheme is deemed to be best. You know what's "best", and that's a fixed point scheme. For more detail, see http://en.cppreference.com/w/cpp/io/manip .
Even better is not to use floating point numbers at all when dealing with money. It is far better to use some fixed point arithmetic package.
float generally has 24 binary bits of precision which means that it can store about 6 decimal digits of precision so if your number is greater than 100000 you're not going to get any precision at all for decimal digits.
You should use double which has about 15 decimal digits of precision in this case instead of float
That answers your specific question most likely but if this is for money you probably shouldn't be using a floating format at all, as they can;t exactly represent 0.01 as a value for example, so all your calculations will be approximate and you probably don't want that when dealing with money. Generally hold the number of pence/cents/whatever in an integer and be careful :) Or even better a class specially designed for handling money values as there are often legal requirements on rounding etc.

c++ how to obtain randon numbers and how to save a double with ony two decimals?

I have the following :
int R=25;
double pi=3.14;
double r=R*sqrt(rand());
cout<<"r: "<<r<<endl;
double th=2*pi*rand();
cout<<"th: "<<theta<<endl;
I want to convert : r=1.98 and th=5.08. I would also like the double result=r*th to be with 2 zecimals.
when I print double result =r*th; the number is very huge and is not realistic.
How to change the r and th value to 1.98 and 5.08? How to solve this?
I need to change each double to just 2 decimals after "."
I am working in c++ under ubuntu.
Thx appreciate
To produce random values in the range you specified, try this:
r = (R*(rand()/(RAND_MAX + 1.0)));
th = (2*3.14*(rand()/(RAND_MAX + 1.0)));
The expression rand()/(RAND_MAX+1.0) produces values in the range [0,1.0). Multiplying that by the range limit gives you the numbers you want.
Note: this doesn't limit the numbers to two decimal places, which is more a function of how you print them. To print them with two decimal places, try this:
std::cout << std::fixed << std::setprecision(2) << r << "\n";
std::cout << std::fixed << std::setprecision(2) << th << "\n";
std::cout << std::fixed << std::setprecision(2) << (r*th) << "\n";
See this question: C++ generating random numbers
If you need to make both numbers smaller by the same amount then you can simply divide them both by the same number. You'll lose approximately the same precision either way.
If you really want to completely alter the result by chopping off the exponent then you could probably dig into the double number format itself and separate out the mantissa.
Why you would do this is a mystery to me.