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.
Related
my goal is to turn a double's fraction part into an integer, for example: turn 0.854 into 854 or turn 0.9321 into 9321 (the whole part of the double is always 0)
i was doing it like this, but i dont know how to fill the while's parameters to make it stop when variable x becomes a whole number without a fraction:
double x;
cin >> x;
while(WHAT DO I TYPE HERE TO MAKE IT STOP WHEN X BECOMES A WHOLE NUMBER){
x *= 10;
}
it would be best if i could do it with a loop, but if it is not possible, i am open to other suggestions :)
That question has no answer in a mathematical/logical sense. You have to read how floating point numbers in computers work, see e.g.
https://en.wikipedia.org/wiki/Floating-point_arithmetic
and understand that they are not decimal point numbers in memory. A floating point number in memory consists of three actual numbers: significant * base^{exponent} and according to IEEE the base used is "2" in basically any modern floating point data, but in even more generality, the base can be anything. Thus, whatever you have in your mind, or even see on your screen as output, is a misleading representation of the data in memory. Your question is, thus, mainly a misconception of how floating point numbers in computers work...
Thus, what you specifically ask for does in general not exist and cannot be done.
However, there may be special application for output formatting or whatever where something like this may make sense -- but then the specific goal must be clearly stated in the question here. And in some of such cases, using a "string-based" approach, as you suggested, will work. But this is not an answer to your generic question and has the high potential to also mislead others in the future.
Actually, one way to make your question obvious and clear is to also specify a fixed desired precision, thus, numbers after the decimal point. Then the answer is quite trivially and correctly:
long int value = fraction * pow(10, precision);
In this scenario you know 100% what your are doing. And if you really like you could subsequently remove zeros from the right side...
int nTrailingZeros = 0;
while (value%10 == 0) {
value /= 10;
++nTrailingZeros;
}
However there is another principle problem on a numerical level: there is no mathematical difference between, e.g., 000003 and just 3, thus in any such application the input 0.000003 will give the same results as 0.0003 or 0.3 etc. This cannot be a desired functionality... it is pretty useless to ask about the *value of the fractional part of a floating point number. But, since we have a known precision`, we can do:
cout << setw(precision-ntrailing) << setfill('0') << value << endl;
which will fill in the eventually missing leading zeros.
See this complete tested test code
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
double v = 0.0454243252;
int precision = 14;
long int value = v*pow(10,precision);
cout << value << endl;
// 4542432520000
int nTrailingZeros = 0;
while (value%10 == 0) {
value /= 10;
++nTrailingZeros;
}
cout << value << endl;
// 454243252
cout << setw(precision-ntrailing) << setfill('0') << value << endl;
// 0454243252
}
Here is a possible approach:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
int main()
{
cout << "Enter Number: ";
double user_input;
cin >> user_input;
int user_input_to_int = int(user_input);
double decimal_value = user_input - user_input_to_int;
ostringstream oss;
oss << std::noshowpoint << decimal_value;
string num_str = oss.str();
int str_length = num_str.size()-2;
int multiplier = 1;
for (int x = 0; x < str_length; x++)
{
multiplier *= 10;
}
cout << "\n";
cout << "Whole number: " << user_input_to_int << endl;
cout << "Decimal value: " << decimal_value*multiplier << endl;
}
Compare the difference between double and integer part. It is working only if x is less than 2^63.
while (x - long long(x) > 0)
find 2 real numbers find the fractional part smaller than these numbers
i just started programming and wrote a currency converter programme that needs to be accurate to 2 decimals (using double) However i would not like trailing zeroes but users should still be able to input decimals with set precision rounding it off to a whole integer
Here is the code:
#include <iostream>
#include <iomanip>
using namespace std;
const double DOLLAR = 0.05917;
const double EUROS = 0.05681;
int main()
{
double rand;
double equivD;
double equivE;
cout << setprecision(2)<<fixed;
cout << " Enter Rand amount: ";
cin >> rand;
cout << rand << " Rand(s)= ";
equivD= (rand*DOLLAR);
cout << equivD<< " Dollar(s)\n ";
cout << rand << " Rand(s)= ";
equivE= (rand*EUROS);
cout << equivE<< " Euro(s)\n ";
return 0;
}
Output if entered value is a 1000 is:
1000.00= 57.24 Dollars
1000.00= answer
If an integer is inputed without decimals I would like to remove the .00 but still keep it as a double in case a decimal is inputed. How do I do this?
Don't use floating point for money: you'll be off on the 15th significant figure; which, by the time you've consumed two digits for the cents, is not particularly large.
In your case, use a 64 bit integral type and work in cents, tweaking your formatting when you want to display computed values. (Don't forget to round correctly when using the FX rates).
If you want different formatting for different cases, I would test to see if there is a decimal.
In your example, with doubles, this could be
if( 0 == (((long long)(rand*100)) % 100) )
cout << setprecision(0);
This multiplies rand by 100, converts it to an integral type, and then checks if the right two digits are both zero.
The Better Solution
Use an integral type (like int or long long) to store the value as "hundredths of rands" (like Bathsheba suggested). This reduces rounding errors. To test for the decimal and output, just use a modulo, like this:
cout << (rand / 100); // Integer division
if( 0 != (rand % 100) ) // Are there any amounts less than one rand?
cout << '.' << (rand % 100);
Of course, there is still the issue of reading in the user input to a long long, but I'm not an expert with cin.
I am using C++ and I would like to format doubles in the following obvious way. I have tried playing with 'fixed' and 'scientific' using stringstream, but I am unable to achieve this desired output.
double d = -5; // print "-5"
double d = 1000000000; // print "1000000000"
double d = 3.14; // print "3.14"
double d = 0.00000000001; // print "0.00000000001"
// Floating point error is acceptable:
double d = 10000000000000001; // print "10000000000000000"
As requested, here are the things I've tried:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
string obvious_format_attempt1( double d )
{
stringstream ss;
ss.precision(15);
ss << d;
return ss.str();
}
string obvious_format_attempt2( double d )
{
stringstream ss;
ss.precision(15);
ss << fixed;
ss << d;
return ss.str();
}
int main(int argc, char *argv[])
{
cout << "Attempt #1" << endl;
cout << obvious_format_attempt1(-5) << endl;
cout << obvious_format_attempt1(1000000000) << endl;
cout << obvious_format_attempt1(3.14) << endl;
cout << obvious_format_attempt1(0.00000000001) << endl;
cout << obvious_format_attempt1(10000000000000001) << endl;
cout << endl << "Attempt #2" << endl;
cout << obvious_format_attempt2(-5) << endl;
cout << obvious_format_attempt2(1000000000) << endl;
cout << obvious_format_attempt2(3.14) << endl;
cout << obvious_format_attempt2(0.00000000001) << endl;
cout << obvious_format_attempt2(10000000000000001) << endl;
return 0;
}
That prints the following:
Attempt #1
-5
1000000000
3.14
1e-11
1e+16
Attempt #2
-5.000000000000000
1000000000.000000000000000
3.140000000000000
0.000000000010000
10000000000000000.000000000000000
There is no way for a program to KNOW how to format the numbers in the way that you are describing, unless you write some code to analyze the numbers in some way - and even that can be quite hard.
What is required here is knowing the input format in your source code, and that's lost as soon as the compiler converts the decimal input source code into binary form to store in the executable file.
One alternative that may work is to output to a stringstream, and then from that modify the output to strip trailing zeros. Something like this:
string obvious_format_attempt2( double d )
{
stringstream ss;
ss.precision(15);
ss << fixed;
ss << d;
string res = ss.str();
// Do we have a dot?
if ((string::size_type pos = res.rfind('.')) != string::npos)
{
while(pos > 0 && (res[pos] == '0' || res[pos] == '.')
{
pos--;
}
res = res.substr(pos);
}
return res;
}
I haven't actually tired it, but as a rough sketch, it should work. Caveats are that if you have something like 0.1, it may well print as 0.09999999999999285 or some such, becuase 0.1 can not be represented in exact form as a binary.
Formatting binary floating-point numbers accurately is quite tricky and was traditionally wrong. A pair of papers published in 1990 in the same journal settled that decimal values converted to binary floating-point numbers and back can have their values restored assuming they don't use more decimal digits than a specific constraint (in C++ represented using std::numeric_limits<T>::digits10 for the appropriate type T):
Clinger's "How to read floating-point numbers accurately" describes an algorithm to convert from a decimal representation to a binary floating-point.
Steele/White's "How to print floating-point numbers accurately" describes how to convert from a binary floating-point to a decimal decimal value. Interestingly, the algorithm even converts to the shortest such decimal value.
At the time these papers were published the C formatting directives for binary floating points ("%f", "%e", and "%g") were well established and they didn't get changed to the take the new results into account. The problem with the specification of these formatting directives is that "%f" assumes to count the digits after the decimal point and there is no format specifier asking to format numbers with a certain number of digits but not necessarily starting to count at the decimal point (e.g., to format with a decimal point but potentially having many leading zeros).
The format specifiers are still not improved, e.g., to include another one for non-scientific notation possibly involving many zeros, for that matter. Effectively, the power of the Steele/White's algorithm isn't fully exposed. The C++ formatting, sadly, didn't improve over the situation and just delegates the semantics to the C formatting directives.
The approach of not setting std::ios_base::fixed and using a precision of std::numeric_limits<double>::digits10 is the closest approximation of floating-point formatting the C and C++ standard libraries offer. The exact format requested could be obtained by getting the digits using using formatting with std::ios_base::scientific, parsing the result, and rewriting the digits afterwards. To give this process a nice stream-like interface it could be encapsulated with a std::num_put<char> facet.
An alternative could be the use of Double-Conversion. This implementation uses an improved (faster) algorithm for the conversion. It also exposes interfaces to get the digits in some form although not directly as a character sequence if I recall correctly.
You can't do what you want to do, because decimal numbers are not representable exactly in floating point format. In otherwords, double can't precisely hold 3.14 exactly, it stores everything as fractions of powers of 2, so it stores it as something like 3 + 9175/65536 or thereabouts (do it on your calculator and you'll get 3.1399993896484375. (I realize that 65536 is not the right denominator for IEEE double, but the gist of it is correct).
This is known as the round trip problem. You can't reliable do
double x = 3.14;
cout << magic << x;
and get "3.14"
If you must solve the round-trip problem, then don't use floating point. Use a custom "decimal" class, or use a string to hold the value.
Here's a decimal class you could use:
https://stackoverflow.com/a/15320495/364818
I am using C++ and I would like to format doubles in the following obvious way.
Based on your samples, I assume you want
Fixed rather than scientific notation,
A reasonable (but not excessive) amount of precision (this is for user display, so a small bit of rounding is okay),
Trailing zeros truncated, and
Decimal point truncated as well if the number looks like an integer.
The following function does just that:
#include <cmath>
#include <iomanip>
#include <sstream>
#include <string>
std::string fixed_precision_string (double num) {
// Magic numbers
static const int prec_limit = 14; // Change to 15 if you wish
static const double log10_fuzz = 1e-15; // In case log10 is slightly off
static const char decimal_pt = '.'; // Better: use std::locale
if (num == 0.0) {
return "0";
}
std::string result;
if (num < 0.0) {
result = '-';
num = -num;
}
int ndigs = int(std::log10(num) + log10_fuzz);
std::stringstream ss;
if (ndigs >= prec_limit) {
ss << std::fixed
<< std::setprecision(0)
<< num;
result += ss.str();
}
else {
ss << std::fixed
<< std::setprecision(prec_limit-ndigs)
<< num;
result += ss.str();
auto last_non_zero = result.find_last_not_of('0');
if (result[last_non_zero] == decimal_pt) {
result.erase(last_non_zero);
}
else if (last_non_zero+1 < result.length()) {
result.erase(last_non_zero+1);
}
}
return result;
}
If you are using a computer that uses IEEE floating point, changing prec_limit to 16 is unadvisable. While this will let you properly print 0.9999999999999999 as such, it also prints 5.1 as 5.0999999999999996 and 9.99999998 as 9.9999999800000001. This is from my computer, your results may vary due to a different library.
Changing prec_limit to 15 is okay, but it still leads to numbers that don't print "correctly". The value specified (14) works nicely so long as you aren't trying to print 1.0-1e-15.
You could do even better, but that might require discarding the standard library (see Dietmar Kühl's answer).
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.
http://www.learncpp.com/cpp-tutorial/25-floating-point-numbers/
I have been about this lately to review C++.
In general computing class professors tend not to cover these small things, although we knew what rounding errors meant.
Can someone please help me with how to avoid rounding error?
The tutorial shows a sample code
#include <iomanip>
int main()
{
using namespace std;
cout << setprecision(17);
double dValue = 0.1;
cout << dValue << endl;
}
This outputs
0.10000000000000001
By default float is kept 6-digits of precisions. Therefore, when we override the default, and asks for more (n this case, 17!!), we may encounter truncation (as explained by the tutorial as well).
For double, the highest is 16.
In general, how do good C++ programmers avoid rounding error?
Do you guys always look at the binary representation of the number?
Thank you.
The canonical advice for this topic is to read "What Every Computer Scientist Should Know About Floating-Point Arithmetic", by David Goldberg.
In other words, to minimize rounding errors, it can be helpful to keep numbers in decimal fixed-point (and actually work with integers).
#include <iostream>
#include <iomanip>
int main() {
using namespace std;
cout << setprecision(17);
double v1=1, v1D=10;
cout << v1/v1D << endl; // 0.10000000000000001
double v2=3, v2D=1000; //0.0030000000000000001
cout << v2/v2D << endl;
// v1/v1D + v2/v2D = (v1*v2D+v2*v1D)/(v1D*v2D)
cout << (v1*v2D+v2*v1D)/(v1D*v2D) << endl; // 0.10299999999999999
}
Short version - you can't really avoid rounding and other representation errors when you're trying to represent base 10 numbers in base 2 (ie, using a float or a double to represent a decimal number). You pretty much either have to work out how many significant digits you actually have or you have to switch to a (slower) arbitrary precision library.
Most floating point output routines look to see if the answer is very close to being even when represented in base 10 and round the answer to actually be even on output. By setting the precision in this way you are short-circuiting this process.
This rounding is done because almost no answer that comes out even in base 10 will be even (i.e. end in an infinite string of trailing 0s) in base 2, which is the base in which the number is represented internally. But, of course, the general goal of an output routine is to present the number in a fashion useful for a human being, and most human beings in the world today read numbers in base 10.
When you calculate simple thing like variance you can have this kind of problem... here is my solution...
int getValue(double val, int precision){
std::stringstream ss;
ss << val;
string strVal = ss.str();
size_t start = strVal.find(".");
std::string major = strVal.substr(0, start);
std::string minor = strVal.substr(start + 1);
// Fill whit zero...
while(minor.length() < precision){
minor += "0";
}
// Trim over precision...
if(minor.length() > precision){
minor = minor.substr(0, precision);
}
strVal = major + minor;
int intVal = atoi(strVal.c_str());
return intVal;
}
So you will make your calcul in the integer range...
for example 2523.49 became 252349 whit a precision of tow digits, and 2523490 whit a precision of tree digit... if you calculate the mean for example first you convert all value in integer, make the summation and get the result back in double, so you not accumulate error... Error are amplifie whit operation like square root and power function...
You want to use the manipulator called "Fixed" to format your digits correctly so they do not round or show in a scientific notation after you use fixed you will also be able to use set the precision() function to set the value placement to the right of the .
decimal point. the example would be as follows using your original code.
#include <iostream>
#include <iomanip>
int main()
{
using namespace std;
double dValue = 0.19213;
cout << fixed << setprecision(2) << dValue << endl;
}
outputs as:
dValue = 0.19