Precision in double and other floating numbers - c++

I am having trouble getting my program to output the correct precision for my doubles. Say I have a
double d;
After running some algorithm, I get d as my output. I want to set the precision of my d variable to 4 points of precision after decimal. I should be able to do this like so:
cout << setprecision(4) << d;
The problem is that if I if d is an integer, then no decimal placed are printed.
For example, if d == 120, then my program will print 120. I want it to print 120.0000 instead. How do I get my program to always print 4 decimal places?

You need to be using fixed precision to output a fixed number of decimal points. You should to tell the stdout stream (cout) that you want to use fixed precision.
std::cout << std::fixed << std::setprecision(4) << d;

Related

cout prints inaccurate result and printf prints accurate result

The following code in C++:
double x = 500000.6;
printf("%f\n", x);
cout << x << endl;
prints the following:
500000.600000
500001
Why cout isn't printing the correct value (500000.6)?
Putting the following line as the beginning of the code makes cout prints correct result:
cout.precision(7);
However, setting the precision to 6 (which is the default anyways) doesn't print the expected result.
Why this happen? I have only 1 digit after the decimal point, not 7 digits!
By default, the precision is the total number of significant digits. It's not the number of digits after the decimal point. 500000.6 has seven significant digits, 500001 has only six.
Try this instead
cout << fixed << setprecision(1) << x << endl;
When used for fixed format, the precision is the number of digits after the decimal point.

How to set precision of a float?

For a number a = 1.263839, we can do -
float a = 1.263839
cout << fixed << setprecision(2) << a <<endl;
output :- 1.26
But what if i want set precision of a number and store it, for example-
convert 1.263839 to 1.26 without printing it.
But what if i want set precision of a number and store it
You can store the desired precision in a variable:
int precision = 2;
You can then later use this stored precision when converting the float to a string:
std::cout << std::setprecision(precision) << a;
I think OP wants to convert from 1.263839 to 1.26 without printing the number.
If this is your goal, then you first must realise, that 1.26 is not representable by most commonly used floating point representation. The closest representable 32 bit binary IEEE-754 value is 1.2599999904632568359375.
So, assuming such representation, the best that you can hope for is some value that is very close to 1.26. In best case the one I showed, but since we need to calculate the value, keep in mind that some tiny error may be involved beyond the inability to precisely represent the value (at least in theory; there is no error with your example input using the algorithm below, but the possibility of accuracy loss should always be considered with floating point math).
The calculation is as follows:
Let P bet the number of digits after decimal point that you want to round to (2 in this case).
Let D be 10P (100 in this case).
Multiply input by D
std::round to nearest integer.
Divide by D.
P.S. Sometimes you might not want to round to the nearest, but instead want std::floor or std::ceil to the precision. This is slightly trickier. Simply std::floor(val * D) / D is wrong. For example 9.70 floored to two decimals that way would become 9.69, which would be undesirable.
What you can do in this case is multiply with one magnitude of precision, round to nearest, then divide the extra magnitude and proceed:
Let P bet the number of digits after decimal point that you want to round to (2 in this case).
Let D be 10P (100 in this case).
Multiply input by D * 10
std::round to nearest integer.
Divide by 10
std::floor or std::ceil
Divide by D.
You would need to truncate it. Possibly the easiest way is to multiply it by a factor (in case of 2 decimal places, by a factor of 100), then truncate or round it, and lastly divide by the very same factor.
Now, mind you, that floating-point precision issues might occur, and that even after those operations your float might not be 1.26, but 1.26000000000003 instead.
If your goal is to store a number with a small, fixed number of digits of precision after the decimal point, you can do that by storing it as an integer with an implicit power-of-ten multiplier:
#include <stdio.h>
#include <math.h>
// Given a floating point value and the number of digits
// after the decimal-point that you want to preserve,
// returns an integer encoding of the value.
int ConvertFloatToFixedPrecision(float floatVal, int numDigitsAfterDecimalPoint)
{
return (int) roundf(floatVal*powf(10.0f, numDigitsAfterDecimalPoint));
}
// Given an integer encoding of your value (as returned
// by the above function), converts it back into a floating
// point value again.
float ConvertFixedPrecisionBackToFloat(int fixedPrecision, int numDigitsAfterDecimalPoint)
{
return ((float) fixedPrecision) / powf(10.0f, numDigitsAfterDecimalPoint);
}
int main(int argc, char ** arg)
{
const float val = 1.263839;
int fixedTwoDigits = ConvertFloatToFixedPrecision(val, 2);
printf("fixedTwoDigits=%i\n", fixedTwoDigits);
float backToFloat = ConvertFixedPrecisionBackToFloat(fixedTwoDigits, 2);
printf("backToFloat=%f\n", backToFloat);
return 0;
}
When run, the above program prints this output:
fixedTwoDigits=126
backToFloat=1.260000
If you're talking about storing exactly 1.26 in your variable, chances are you can't (there may be an off chance that exactly 1.26 works, but let's assume it doesn't for a moment) because floating point numbers don't work like that. There are always little inaccuracies because of the way computers handle floating point decimal numbers. Even if you could get 1.26 exactly, the moment you try to use it in a calculation.
That said, you can use some math and truncation tricks to get very close:
int main()
{
// our float
float a = 1.263839;
// the precision we're trying to accomplish
int precision = 100; // 3 decimal places
// because we're an int, this will keep the 126 but lose everything else
int truncated = a * precision; // multiplying by the precision ensures we keep that many digits
// convert it back to a float
// Of course, we need to ensure we're doing floating point division
float b = static_cast<float>(truncated) / precision;
cout << "a: " << a << "\n";
cout << "b: " << b << "\n";
return 0;
}
Output:
a: 1.26384
b: 1.26
Note that this is not really 1.26 here. But is is very close.
This can be demonstrated by using setprecision():
cout << "a: " << std:: setprecision(10) << a << "\n";
cout << "b: " << std:: setprecision(10) << b << "\n";
Output:
a: 1.263839006
b: 1.25999999
So again, it's not exactly 1.26, but very close, and slightly closer than you were before.
Using a stringstream would be an easy way to achieve that:
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
int main() {
stringstream s("");
s << fixed << setprecision(2) << 1.263839;
float a;
s >> a;
cout << a; //Outputs 1.26
return 0;
}

Why is the output different from what I expected?

I run this code but the output was different from what I expected.
The output:
c = 1324
v = 1324.99
I expected that the output should be 1324.987 for v. Why is the data in v different from output?
I'm using code lite on Windows 8 32.
#include <iostream>
using namespace std;
int main()
{
double v = 1324.987;
int n;
n = int (v);
cout << "c = " << n << endl;
cout << "v = " << v << endl;
return 0;
}
Floating point types inherit rounding errors as a result of their fixed width representations. For more information, see What Every Computer Scientist Should Know About Floating-Point Arithmetic.
The default precision when printing with cout is 6, so only 6 decimal places will be displayed. The number is rounded to the nearest value, that's why you saw 1324.99. You need to set a higher precision to see the more "correct" value
However, setting the precision too high may print out a lot of garbage digits behind, because binary floating-point types cannot store all decimal floating-point values exactly.

How to prevent rounding error in c++?

How I can prevent rounding error in C++ or fix it?
Example:
float SomeNumber = 999.9999;
cout << SomeNumber << endl;
It prints out 1000!
You can alter the rounding done by cout by setting the precision.
cout.precision(7);
float SomeNumber = 999.9999;
cout << SomeNumber << endl;
Alternatively, you can use printf from cstdio.
By default, formatted output via std::ostream rounds floating-point values to six significant decimal figures. You need seven to avoid your number being rounded to 1000:
cout << setprecision(7) << SomeNumber << endl;
^^^^^^^^^^^^^^^
Also, be aware that you're close to the limit of the precision of float, assuming the commonly-used 32-bit IEEE representation. If you need more than seven significant figures then you'll need to switch to double. For example, the following prints 1000, no matter how much precision you specify:
float SomeNumber = 999.99999; // 8 significant figures
cout << setprecision(10) << SomeNumber << endl;
To prevent your output being rounded, use setprecision in iomanip.
float SomeNumber = 999.9999;
std::cout << SomeNumber << std::endl; //outputs 1000
std::cout << std::setprecision (7) << SomeNumber << std::endl; //outputs 999.9999
return 0;
The actual value stored in SomeNumber will always be 999.9999 though, so you don't need to worry about the value itself (unless you need more precision than float provides).
As mentioned previously, if you're looking only for cout rounding fix, use the .precision function. If you're referring to the incapacity of floating points to represent every possible fractions, read below:
You can't avoid such rounding errors using floating point numbers. You need to represent your data in a different way. For example, if you want 5 digits of precision, just store it as a long which represent the number of your smallest units.
I.e. 5.23524 w/ precision at 0.00001 can be represented in a long (or int if your range of values fit) as 523524. You know the units are 0.00001 so you can easily make it work.

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.