I recently picked up the c++ programming language, and I'm trying to calculate the digits of 'e' for a Calculus Project at school. I'll paste the pgoram that I've written below. It's based on e= lim(1+1/x)^x, as x-> infinity. In this program, I set x=100,000. I also set x=1,000,000 and noticed that the answers are somehow being subjected to a round-off error, instead of becoming longer in length.
Program:
#include <iostream>
#include <math.h>
using namespace std;
long double sum;
int main()
{
long double x=100000;
sum= (pow((1+(1/x)),(x)));
cout<<sum;
}
Any tips/ advice in making it print out more digits would be great. Thanks in advance.
On the first hand long double is limited in the number of digits it can produce, and because of how the real numbers are implemented it won't produce exact results.
But, to answer your question you can set cout's precision by doing
cout.precision(15);
cout << sum;
Also see this answer for more explanations and details see
How do I print a double value with full precision using cout?
Double in c++ is a floating point number. For accurate calculation like this you need use decimal number.
See this answer about decimal in cpp
Related
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
Below is the program I've written to find the exponent of 6, but I this its giving wrong output or I may be wrong somewhere, I'm unable to figure out here.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll t;
cin>>t;
cout<<log(t)/log(6)<<"\n";
cout<<floor(log(t)/log(6))<<"\n";
cout<<ceil(log(t)/log(6));
return 0;
}
Input:-
216
Output:-
3
3
4
Since 216 can be written as 6*6*6, so whether there is ceil or floor the output should be 3 in all three cases.
Answering to my own question, this problem can be solved by setting small precision(here up to 2 decimal digits), below is the program for the same.
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
cout<<log(t)/log(6)<<"\n";
cout<<floor((floor(log(t)/log(6)*100.0)/100.0))<<"\n";
cout<<ceil((floor(log(t)/log(6)*100.0)/100.0));
return 0;
}
The log function - like most floating point calculations - is imprecise. There is often tiny amount of error in the result. In your case, you did not get the exact 3, but some value slightly greater than 3. When you apply ceil or floor to such imprecise result, you may increase or reduce the amount of the error up to a whole number. In this case you increased the error by ceiling the result from nearly correct integer to exactly following integer).
If you want to find the exponent of an integer with respect to a given radix, then repeated division and checking the remainder is a good starting point. There are faster ways (related to exponentation by squaring) which you could investigate if you want to squeeze out more performance.
The problem is that using the ratio of two log calls and truncating that to an int is bound to give you an inexact answer since the result of a log most likely cannot be represented exactly as a floating point value, and the log function itself may not recover the best floating point value possible (neither the C++ standard nor IEEE754 insist on that).
Finally, on #define ll long long, don't do that. It only serves to obfuscate. And #include<bits/stdc++.h> is not portable C++.
I am trying to calculate the sum of digits of 2^1000 in c++.
As you can see, the value of 2^1000 contains many zeroes and some digits, but even then the output of sum turns out to be in decimals.
My code is the following:
#include <bits/stdc++.h>
using namespace std;
main() {
cout<<fixed;
long double a=pow(2,1000),sum=0;
cout<<"2^1000 is"<<a<<"\n";
while(a) {
sum+=fmod(a,10);
a/=10;
}
cout<<sum;
}
I used fmod() since the % operator is not overloaded for long double, I had never used fmod() earlier but used it as mentioned here.
I don't really think fmod() is doing any mistake here, so any suggestion why the output of sum is in decimals? Futher, the correct answer should be 1366.
Here is the sample output:
Okay, so solved my problem by using this Bigint library!
You can't store 2^1000 in a single variable in C++. 2^1000 needs at least 1000 bits to be stored in binary, no variable of primitive type is long enough. So the first printed result is already wrong, remember that no power of 2 contains an ending 0 (2*2=4, 4*2=8, 8*2=16, 6*2=2). Then you cannot rely on the result of fmod.
2^1000=10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376
Could we work with big numbers up to 10^308.
How can I calculate the 11^105 using just double?
The answer of (11^105) is:
22193813979407164354224423199022080924541468040973950575246733562521125229836087036788826138225193142654907051
Is it possible to get the correct result of 11^105?
As I know double can handle 10^308 which is much bigger than 11^105.
I know that this code is wrong:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
double n, p, x;
cin >> n >> p;
//scanf("%lf %lf", &n,&p);
x = exp(log((double)n)*p);
//printf("%lf\n", x);
cout << x <<endl;
return 0;
}
Thanks.
double usually has 11bit for exp (-1022~1023 normalized), 52bit for fact and 1bit for sign. Thus 11^105 cannot be represented accurately.
For more explanation, see IEEE 754 on Wikipedia
Double can hold very large results, but not high precision. In constrast to fixed point numbers, double is floating point real number. This means, for the same accuracy double can shift the radix to handle different range of number and thus you see high range.
For your purpose, you need some home cooked big num library, or you can find one readily available and written by someone else.
BTW my home cooked recipe gives different answer for 11105
Confirmed with this haskell code
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I apologize for asking yet another rounding question. However, all the search has not yielded a satisfactory solution to my problem. The only possible answer is that what I am looking for may not be possible at all. Just wanted to make sure if the experts think the same.
So, here is my sample code:
double Round(double dbVal, int nPlaces)
{
const double dbShift = pow(10.0, nPlaces);
return floor(dbVal * dbShift + 0.5) / dbShift;
}
main()
{
string sNum = "1.29585";
double dNum = stod(sNum);
int iNumDecimals = 5;
double dRoundedNum = Round(dNum, iNumDecimals);
}
The number sNum is read as a string from a file. For example, the number in the file is 1.29585. I convert it to double using stod. dNum comes out to be 1.295849999999.... I would like to get back 1.29585 in double. Using a Round function as shown above does not help. The round function also returns 1.295849999999....
Is it possible to get back the exact 1.29585 at all? Any other possible solution?
Thanks in advance for any advice.
Your number is rounded to the closest representable double to the number you provided ( 1.29585 ). To 17 places, it is: 1.29584999999999995
The next largest representable double-precision number is 1 / 252 larger than that: 1.29585000000000017.
That's roughly 1 part in 5 quadrillion. An error of that magnitude, scaled to the circumference of the entire solar system, would only be about 8 centimeters.
So, in terms of rounding, the double you have is correctly rounded to the nearest representable binary value.
By default, floating point numbers are stored in binary. Just as you can't express 1/3 as an exact decimal fraction (you can approximate it with "0.33333333", extending out the 3s until you get sick of it), you can't express all round decimal values exactly in binary.
If you're curious what the above two values look like in binary: (You can refer to the diagram and description here to understand how to interpret that hexadecimal value if you are interested.)
1.29584999999999995 == 0x3FF4BBCD35A85879
1.29585000000000017 == 0x3FF4BBCD35A8587A
For your zillions of calculations, this approximate representation should cause no problem, unless you're computing a series of values that need to be rounded to an exact number of decimal places. Typically, that's only necessary if you're computing actual bank transactions or the like. Bankers want decimal rounding, so that their computations today match the way computations were done 100 years ago so that they have continuity between the pre- and post-computer eras, not because they're magically more accurate.
Double precision arithmetic carries 16 to 17 decimal positions of precision. The fact that it doesn't print as a nice round number of decimal digits doesn't mean it's inaccurate. If you compare the calculation the computer makes with double precision to the same calculation you'd do by hand (even with the aid of a standard calculator displaying 9 to 12 digits of precision), the computer's double precision arithmetic will generally come out ahead.
What you most likely want to do is to make sure to print out your final calculations to the appropriate number of decimal places. For example, you can use std::setprecision() from <iomanip> to control the precision of values printed via std::cout.
EDIT: If your application actually requires decimal arithmetic and decimal rounding, then you will need to look into decimal floating point support, either built into the compiler or in a 3rd party library. Some recent compilers do have support for this, and some processors even have hardware support for decimal floating point. GCC has decimal floating point extensions, for example, as does Intel's compiler. In contrast, Microsoft suggests finding a BCD library, it seems.
Try this way, i donĀ“t remember the format for double right now, i use float.
float num;
sscanf("1.29585", "%f", &num);
std::cout << num << std::endl;
The "I whipped it up in Haskell and translated it" answer:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
double d = 1.2958499999999;
cout << setprecision(15) << d << endl;
cout << setprecision(15) << double(round(d * 1e5) / 1e5) << endl;
return 0;
}
// outputs:
// 1.2958499999999
// 1.29585
It is hardly a general answer, but it is correct to the letter of the question. I highly recommend understanding the evil that is IEEE floating point using e.g. Jim Buck's reference rather than putting this hack to any great use.
I'm teaching myself C++ and on this practice question it asks to write code that can calculate PI to >30 digits. I learned that double / long double are both 16 digits precise on my computer.
I think the lesson of this question is to be able to calculate precision beyond what is available. Therefore how do I do this? Is it possible?
my code for calculating Pi right now is
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <iomanip>
using namespace std;
int main(){
double pi;
pi = 4*atan(1.0);
cout<<setprecision(30)<<pi;
return 0;
}
Output is to 16 digits and pi to 30 digits is listed below for comparison.
3.1415926535897931
3.141592653589793238462643383279
Any suggestions for increasing precision or is this something that won't matter ever? Alternatively if there is another lesson you think I should be learning here feel free to offer it. Thank you!
You will need to perform the calculation using some other method than floating point. There are libraries for doing "long math" such as GMP.
If that's not what you're looking for, you can also write code to do this yourself. The simplest way is to just use a string, and store a digit per character. Do the math just like you would do if you did it by hand on paper. Adding numbers together is relatively easy, so is subtracting. Doing multiplication and division is a little harder.
For non-integer numbers, you'll need to make sure you line up the decimal point for add/subtract...
It's a good learning experience to write that, but don't expect it to be something you knock up in half an hour without much thought [add and subtract, perhaps!]
You can use quad math, builtin type __float128 and q/Q suffixes in GCC/clang.
#include <stdio.h>
#include <quadmath.h>
int main ()
{
__float128 x = strtoflt128("1234567891234567891234567891234566", nullptr);
auto y = 1.0q;
printf("%.Qf", x + y); // there is quadmath_snprintf, but this also works fine
return 0;
}