C++, output of one digit after the decimal - c++

I'm new in C++ and would like to get some help.
I don't understand why I'm getting an output of only one digit after the decimal on the sum below.
I have tried to solve this with no success.
int main()
{
double alt, t;
t = 4.5;
// function for calculating the altitude over time.
alt = (-0.12)*pow(t, 4) +(12.0)*pow(t, 3) -(380.0)*pow(t, 2) +(4100.0)*t +220.0;
cout << alt << endl;
return 0;
}

The default behaviour of cout is to print six significant digits of floating points. You can change that with:
cout.precision(10);
cout << alt << endl;
which gives the output:
12019.2925
which seems to be the correct solution.
You should not try to set the precision to anything higher than roughly 15, because that is about the precision limit of the double type (typically). You can use the numeric_limits<double>::digits10 from <limits> to make sure what precision you actually have.

Related

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;
}

Multiplying doubles in C++ error

I have a seemingly simple c++ issue that's bothering me. The output of the code
#include <iostream>
using namespace std;
int main() {
// your code goes here
double c = 9.43827 * 0.105952 ;
cout << c << endl ;
return 0;
}
is 1. Just 1. I guess this is due to precision loss based on how doubles are stored in c++ but surely there must be a way in c++ to get some sort of precision (2 or 3 decimal places) in the result.
It's not precision loss in storage, it's precision loss in converting to text. The stream inserter for double defaults to six significant digits. The product here, 1.000003583, rounded to six significant digits, is 1.00000. In addition, if you haven't set showpoint, the trailing zeros and the decimal point will be suppressed, so you'll see a bare 1. To get the decimal point to show, use std::cout << std::showpoint << c << '\n';. To see more significant digits, use std::cout << std::setprecision(whatever) << c << '\n';, where whatever is the number of digits you want the formatter to use.
#include <stdio.h>
int main() {
// your code goes here
double c = ((double)9.43827) * 0.105952 ;
for(int i = (sizeof(double)*8)-1; i >= 0; i-- ) {
printf("%ld", (*(long*)&c>>i)&1);
}
}
If you run that, you can clearly see the bit representation of your double is not the integer value 1. You're not losing any data.
0011111111110000000000000000001111000001110100001010001001001001
but it is very close to 1, so that's what gets printed out.
Try using cout<<setprecision(12)<<c<<endl;
setprecision sets the decimal precision to be used to format floating-point values on output operations.
source

How to express large numbers to two decimal places in C++ Calculator

I am trying to write a calculator in C++ that does the basic functions of /, *, -, or + and shows the answer to two decimal places (with 0.01 precision).
For example 100.1 * 100.1 should print the result as 10020.01 but instead I get -4e-171. From my understanding this is from overflow, but that's why I chose long double in the first place!
#include <iostream>
#include <iomanip>
using namespace std;
long double getUserInput()
{
cout << "Please enter a number: \n";
long double x;
cin >> x;
return x;
}
char getMathematicalOperation()
{
cout << "Please enter which operator you want "
"(add +, subtract -, multiply *, or divide /): \n";
char o;
cin >> o;
return o;
}
long double calculateResult(long double nX, char o, long double nY)
{
// note: we use the == operator to compare two values to see if they are equal
// we need to use if statements here because there's no direct way
// to convert chOperation into the appropriate operator
if (o == '+') // if user chose addition
return nX + nY; // execute this line
if (o == '-') // if user chose subtraction
return nX - nY; // execute this line
if (o == '*') // if user chose multiplication
return nX * nY; // execute this line
if (o == '/') // if user chose division
return nX / nY; // execute this line
return -1; // default "error" value in case user passed in an invalid chOperation
}
void printResult(long double x)
{
cout << "The answer is: " << setprecision(0.01) << x << "\n";
}
long double calc()
{
// Get first number from user
long double nInput1 = getUserInput();
// Get mathematical operations from user
char o = getMathematicalOperation();
// Get second number from user
long double nInput2 = getUserInput();
// Calculate result and store in temporary variable (for readability/debug-ability)
long double nResult = calculateResult(nInput1, o, nInput2);
// Print result
printResult(nResult);
return 0;
}
setprecision tells it how many decimal places you want as an int so you're actually setting it to setprecision(0) since 0.01 get truncated. In your case you want it set to 2. You should also use std::fixed or you'll get scientific numbers.
void printResult(long double x)
{
cout << "The answer is: " << std::fixed << setprecision(2) << x << "\n";
}
working example
It is not due to overflow you get the strange result. Doubles can easily hold numbers in the range you are showing.
Try to print the result without setprecision.
EDIT:
After trying
long double x = 100.1;
cout << x << endl;
I see that it doesn't work on my Windows system.
So I searched a little and found:
print long double on windows
maybe that is the explanation.
So I tried
long double x = 100.1;
cout << (double)x << endl;
which worked fine.
2nd EDIT:
Also see this link provided by Raphael
http://oldwiki.mingw.org/index.php/long%20double
The default floating point presentation switches automatically between presentation like 314.15 and 3.1e2, depending on the size of the number and the maximum number of digits it can use. With this presentation the precision is the maximum number of digits. By default it's 6.
You can either increase the maximum number of digits so that your result can be presented like 314.15, or you can force such fixed point notation by using the std::fixed manipulator. With std::fixed the precision is the number of decimals.
However, with std::fixed very large and very small numbers may be pretty unreadable.
The setprecision() manipulator specifies the number of digits after the decimal point. So, if you want 100.01 to be printed, use setprecision(2).
When you use setprecision(0.01), the value 0.01 is being converted to int, which will have a value of 0.
It wouldn't have hurt if you had actually read the documentation for setprecision() - that clearly specifies an int argument, not a floating point one.

Rounding from math.h incorrect

I'm using the tasks on code abbey to work my way through C++.
I'm trying to use the rounding function by importing math.h and it works for every value that I'm trying to input apart from one pair
when I divide 4991264 by 4 and round it, it outputs the answer as 1.24782e+06
#include <iostream>
#include <math.h>
using namespace std;
int getTotal(){
int total;
cin >> total;
return total;
}
void doMath(int total){
int count;
double holder;
double holder2;
double solution;
solution = 0;
count = 0;
while (count != total){
cout << "enter a number ";
cin >> holder;
cout << "enter a number ";
cin >> holder2;
solution = (holder / holder2);
cout << round(solution) << "\n";
++count;
}
}
int main(){
int total = getTotal();
doMath(total);
return 0;
}
http://ideone.com/f40E1s is the code and the inputs.
Thanks,
A floating point variable keeps a value of a given type (in memory).
This value "rests" there with its own precision, in binary format.
When this value has to be shown or output in someway, typically is converted to decimal format. This conversion can have loss of precision sometimes.
Anyway, when you are doing precise arithmetica operations, as in your example, the conversion to decimal is not, in general, an issue.
What it has to be understood here is that "printing" a value is not the same that "showing the exact value held in memory".
The object cout has predefined ways to show the values you are computing.
The exact value has not changed, it's not, in this case, a problem of bad computing.
Indeed, it's only a matter of how to show this value on screen.
The format used to print the value is: in exponential notation with "only" 6 decimal digits precision.
You need to increase the precision of values when printed, and to avoid exponential notation.
Take a look to this website: Output formatting in C++
Thus, for example, the following code do the job (for a precision of 8 decimal digits):
cout << setiosflags(ios::fixed) << setprecision(8) << round(solution) << "\n";
In general, you have to investigate and practice more about this formatting options.

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.