C++ calculating more precise than double or long double - c++

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

Related

Loss of precision while working with double

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

c++ precision issue in storing floating point numbers

I'm handling some mathematical calculation.
I'm losing precision. But i need extreme precision.
I then used to check the precision issue with the code given below.
Any solution for getting the precision?
#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include <sstream>
#include <iomanip>
using namespace std;
int main(int argc,char** arvx)
{
float f = 1.00000001;
cout << "f: " <<std::setprecision(20)<< f <<endl;
return 0;
}
Output is
f: 1
If you truly want precise representation of these sorts of numbers (ie, with very small fractional components many places beyond the decimal point), then floating point types like float or even the much more precise double may still not give you the exact results you are looking for in all circumstances. Floating point types can only approximate some values with small fractional components.
You may need to use some sort of high precision fixed point C++ type in order to get exact representation of very small fractions in your values, and resulting accurate calculated results when you perform mathematical operations on such numbers. The following question/answers may provide you with some useful pointers: C++ fixed point library?
in c++
float f = 1.00000001;
support only 6 digits after decimal point
float f = 1.000001;
if you want more real calculation use double

Why doesn't my C++ program calculate more digits of 'e'?

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

newtons methods implementation

i have posted a few hours ago question about newtons method,i got answers and want to thanks everybody,now i have tried to implement code itself
#include <iostream>
#include <math.h>
using namespace std;
#define h powf(10,-7)
#define PI 180
float funct(float x){
return cos(x)-x;
}
float derivative (float x){
return (( funct(x+h)-funct(x-h))/(2*h));
}
int main(){
float tol=.001;
int N=3;
float p0=PI/4;
float p=0;
int i=1;
while(i<N){
p=p0-(float)funct(p0)/derivative(p0);
if ((p-p0)<tol){
cout<<p<<endl;
break;
}
i=i+1;
p0=p;
if (i>=N){
cout<<"solution not found "<<endl;
break;
}
}
return 0;
}
but i writes output "solution not found",in book after three iteration when n=3 ,it finds solution like this .7390851332,so my question is how small i should change h or how should i change my code such that,get correct answer?
Several things:
2 iterations is rarely going to be enough even in the best case.
You need to make sure your starting point is actually convergent.
Be aware of destructive cancellation in your derivative function. You are subtracting two numbers that are very close to each other so the difference will lose a lot of precision.
To expand on the last point, the general method is to decrease h as the value converges. But as I mentioned in your previous question, this "adjusting" h method essentially (algebraically) reduces to the Secant Method.
If you make h too small then your derivative will be innaccurate due to floating point roundoff. Your code would benefit from using double precision rather than single, especially as you are doing differentiation by finite difference. With double precision your value of h would be fine. If you stick to single precision you will need to use a larger value.
Only allowing 2 iterations seems rather restrictive. Make N larger and get your program to print out the number of iterations used.
Also, no need to use pow. Simply write 1e-7.
You're only allowing 2 iterations which may not be enough to get close enough to the answer. If you only have 1 correct bit to start, you can expect to have at best about 4 good bits after 2 iterations. You're looking for 10 bits accuracy (0.001 is roughly 1/2^10), you have to allow at least 2 more iterations.
Moreover, the quadratic convergence property only holds when you're close to the solution. When you're further out, it may take longer to get close to the solution.
The optimal h for computing the numerical derivative using central differences is 0.005 * max(1,|x|) for single-precision (float), where |x| is the absolute value of the argument, x. For double precision, it's about 5e-6 * max(1,|x|).

decimal places and Pow function in c++

Most likely a really simple question, please keep any answers easy to understand I'm still quite new at this:
I'm making a little app, and I need to use powers for a couple of calculations. After a little research I found the pow function in cmath, and have had a play. In the end i came up with this snipped, which works:
#include <iostream>
#include <cmath>
using namespace std;
int main ()
{
float dummy2, test(6.65);
dummy2 = (float) pow((float) 3.57, test);
cout << dummy2;
return 0;
}
and it returns the correct answer (4734.17), but only to two decimal places. I want 5 decimal places preferably.
What did I do wrong here? Am I using the wrong data type (floats)? Or is it a limit of whatever is in the pow function to using only 2dp?
I could, if it came to it just define constants with the values i want, since it's only going to be 4 or 5 sums that I need this precision on, but if it's possible to have the program calculate it that would be great.
Thanks
I would do as fbinder says, and use Doubles for greater precision.
To solve your problem, you have two options, C-style and C++ style.
C-Style
#include <cstdio>
printf("%.5f", dummy2);
C++ Style
#include <iomanip>
std::cout << setprecision(5) << dummy2 << std::endl;
OR
std::cout.precision(5);
std::cout << dummy2 << std::endl;
// continue to use cout to output 5 decimal places
For a better precision you should use double. Doubles has 15 digits of precision against 7 for floats.