I am using the leibniz method for calculating pi. My program inputs an accuracy number for a calculation of π and then applies the leibniz infinite sum to find an approximate value of π within that accuracy.
I am trying to write a c++ while loop that will input an accuracy number (a double), the initial sum would be equal to zero and initially n would equal zero.
The denominator at n=0, d = 2*n+1 = 1, so the next term would be 4.0/1 = 4.0.
This would then be added to the sum and increment n. If This previous term was greater than the accuracy, the loop would continue.
When the previous term is smaller then the accuracy the number should be outputted and the loop should be exited.
My accuracy is never more than ±0.0001.
My not working code:
while(sum<accuracy)
{
int n = 0;
while(n>10) //this is here due to debugging
{
sum=-4/(2*n+1);
n++;
cout << sum << endl;
}
}
Question:
I am having a hard time coming up with a working while loop that can do what I described above. How do I create such a loop. Please provide an example with explanation.
Make sure that your sum-variable is float/double. It is like our friend commentet you are victim of integer division
double sum;
while(sum<accuracy){
int n=0;
while(n>10)
{
sum=-4.0/(2.0*n+1.0);
n++;
cout << sum << endl;
}
}
Related
I'm trying to write a program that uses the series to compute the value of PI. The user will input how far it wants the program to compute the series and then the program should output its calculated value of PI. I believe I've successfully written the code for this, however it does not do well with large numbers and only gives me a few decimal places. When I tried to use cout << fixed << setprecision(42); It just gave me "nan" as the value of PI.
int main() {
long long seqNum; // sequence number users will input
long double val; // the series output
cout << "Welcome to the compute PI program." << endl; // welcome message
cout << "Please inter the sequence number in the form of an integer." << endl;
cin >> seqNum; // user input
while ( seqNum < 0) // validation, number must be positive
{
cout << "Please enter a positive number." << endl;
cin >> seqNum;
} // end while
if (seqNum > 0)
{
for ( long int i = 0; i < seqNum; i++ )
{
val = val + 4*(pow(-1.00,i)/(1 + 2*i)); // Gregory-Leibniz sum calculation
}// end for
cout << val;
} // end if
return 0;
}
Any help would be really appreciated. Thank you
Your problem involves an elementary, fundamental principle related to double values: a double, or any floating point type, can hold only a fixed upper limit of significant digits. There is no unlimited digits of precision with plain, garden-variety doubles. There's a hard, upper limit. The exact limit is implementation defined, but on modern C++ implementations the typical limit is just 16 or 17 digits of precision, not even close to your desired 42 digits of precision.
#include <limits>
#include <iostream>
int main()
{
std::cout << std::numeric_limits<double>::max_digits10 << std::endl;
return 0;
}
This gives you the maximum digits of precision with your platform/C++ compiler. This shows a maximum of 17 digits of precision with g++ 9.2 on Linux (max_digits10 is C++11 or later, use digits10 with old C++ compilers to show a closely-related metric).
Your desired 42 digits of precision likely far exceed what your modest doubles can handle. There are various special-purpose math libraries that can perform calculations with higher levels of precision, you can investigate those, if you wish.
You did not initialize or assign any value to val, but you are reading it when you get to the first iteration of
val = val + 4*(pow(-1.00,i)/(1 + 2*i));
This cause your program to have undefined behavior. Initialize val, probably to zero:
long double val = 0; // the series output
That aside, as mentioned in the answer of #SamVarshavchik there is a hard limit on the precision you can reach with the built-in floating point types and 42 places significance is almost certainly outside of that. Similarly the integer types that you are using are limited in size to probably at most 2^64 which is approximately 10^19.
Even if these limits weren't the problem, the series requires summation of roughly 10^42 terms to get PI to a precision of 42 places. It would take you longer than the universe has been around to calculate to that precision with all of earths current computing power combined.
I am trying to solve how to multiply and divide two numbers without using * and / operators
I tried using for loops:
for(int a = 1; a<=secondnum; a++)
{
total = firstnum + total;
}
cout << "Total: " << total;
for(b = firstnum; b>=secondnum; b = b-secondnum)
{
total = total + 1;
}
cout << "Answer: " << total;
However this only works for integers...Is there a way for this to work on floating point values?
In the old days (before pocket calculators and the like), logarithm tables were used to turn multiplication and division into a matter of addition and subtraction:
#include <cmath>
double Mult(double a, double b)
{
return exp(log(a)+log(b));
}
double Div(double a, double b)
{
return exp(log(a)-log(b));
}
Note this only works for positive numbers, but it is relatively easy to work with absolute values and then give the result the correct sign.
I actually did this back in high school. I wrote a program that could multiply or divide two arbitrarily-long floating point numbers. Basically, I did it the exact same way I would have done it through long multiplication/division.
I kept both values in arrays of decimal digits.
char firstValue[1024];
char secondValue[1024];
I don't remember if I kept them as ASCII or converted them. It was 40 years ago, after all.
Then I worked it out on paper. Multiply isn't hard, although admittedly I used the * operator to multiply two one-digit values. But you could implement an integerMultiply method.
If you can do it in long hand on paper, you can write an algorithm for it. But it's way too long for an answer here.
I need help figuring out where my code went wrong. I want to reset the values for the loop so that it isn't compiling because my output right now is using past input values in current calculation whereas I want the output to be different every time as though it is the firs time running the code. The code works fine when I don't use the while loop, but then I have to rerun the program each time. I want the output to prompt a new input every time, but not use past inputs in the new calculations. I know I'm not explaining it very well, but I'm just sort of lost. Anything helps!
This is my problem:
An approximate value of pi can be calculated using the series given
below:
pi = 4 · [ 1 – 1/3 + 1/5 – 1/7 + 1/9 ... + (–1 ^ n)/(2n + 1) ]
Write a C++ program to calculate the approximate value of pi using
this series. The program takes an input n that determines the number
of terms in the approximation of the value of pi and outputs the
approximation. Include a loop that allows the user to repeat this
calculation for new values n until the user says she or he wants to
end the program.
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
int n;
double sum=0;
cout << "Enter the number of terms to approximate (or zero to quit):\n";
cin >> n;
if (n == 0)
{
return 0;
}
while (n != 0)
{
{ for(int i=0;i<n;i++)
{
if (i%2==0)
{
sum += 1.0/(2*i+1);
}
else
{
sum += -1.0/(2*i+1);
}
}
cout.setf(ios::showpoint);
cout.precision(3);
cout << "The approximation is " << sum*4 << " using " << n << " terms." << endl;
}
cout << "Enter the number of terms to approximate (or zero to quit):\n";
cin >> n;
}
return 0;
}
This is my output:
This is what the output should be:
You do not reset sum before entering the for loop. Just add
sum=0;
before the for line.
Notice that 2.67 = 6.67 - 4.00.
You want your program to compute a sum for several values of n.
The sum must be initialized to 0 at the beginning of each calculation, inside the while loop.
Actually, it should even be declared there.
C++ doesn't require you to define variables at the start of a function, so it is perfectly legal to write:
while (n != 0)
{
double sum = 0.0;
this would solve your problem. Alternatively, if you want to keep the declaration of sum at the top of the function, just change your code to
while (n != 0)
{
sum = 0.0;
So in this program i am trying to print out the standard deviation of a set of numbers the user enters in. The formula to calculate standard deviation is correct (or as correct as it needs to be) so that is not the problem, but when i run the program everything goes well until the console prints out the results. It prints that totalStandardDeviation = nan
what exactly does than mean? is nan the same as nil? has it lost the value somehow and not been able to find it? thanks for any help you may provide.
#include <iostream>
#include <cmath>
using namespace std;
double returnStandardDeviation(double x, int counter);
double total;
int userInput = 1;
int counter = 0;
double x;
double x1;
double x2;
double standardDeviation;
double totalStandardDeviation;
int main(int argc, const char * argv[])
{
cout << "Please enter a list of numbers. When done enter the number 0 \n";
cin >> userInput;
while (userInput != 0) // As long as the user does not enter 0, program accepts more data
{
counter++;
x = userInput;
returnStandardDeviation( x, counter); // send perameters to function
cout << "Please enter next number \n";
cin >> userInput;
}
cout << "The standard deviation of your "
<< counter
<< " numbers is : "
<< returnStandardDeviation(x, counter);
return 0;
}
double returnStandardDeviation(double x, int counter)
{
x1 += pow(x,2);
x2 += x;
totalStandardDeviation = 0;
totalStandardDeviation += (sqrt(counter * x1 - pow(x2,2))) / (counter * (counter - 1));
return totalStandardDeviation;
}
NaN stands for "Not a number".
NaN can e.g. be the result of:
- Dividing by zero
- Taking the square root of a negative number
In your function, both of these could happen. Division by zero e.g. when counter is <= 1; and x1 and x2 are uninitialized (+= adds the value on the right to their current value - which was never set, and is therefore random gibberish), which can easily lead to your function trying to take the square root of some value < 0.
This expression
counter * x1 - pow(x2,2)
can very easily yield a negative number. You then proceed to take its square root. This would result in a nan.
Next, this one
counter * (counter - 1)
yields 0 when counter is 1. Dividing by zero gives nan.
Your formula is wrong. You are either dividing by zero or taking the square root of a negative number.
Check your formula!
Additional info:
NaN is "Not a number". It is an IEEE floating point value that signals an invalid results, like log(-1), or sqrt(-4).
Additionally, know that Positive Infinity and Negative Infinity are also floating point values.
#include <iostream>
#include <iomanip>
using namespace std;
int a[8], e[8];
void term (int n)
{
a[0]=1;
for (int i=0; i<8; i++)
{
if (i<7)
{
a[i+1]+=(a[i]%n)*100000;
}
/* else
{
a[i+1]+=((a[i]/640)%(n/640))*100000;
}
*/
a[i]=a[i]/(n);
}
}
void sum ()
{
}
int factorial(int x, int result = 1)
{
if (x == 1)
return result;
else return factorial(x - 1, x * result);
}
int main()
{
int n=1;
for (int i=1; i<=30; i++)
{
term(n);
cout << a[0] << " "<< a[1] << " " << a[2] << " "
<< a[3] << " " << a[4] << " " << a[5]<< " "
<< " " << a[6] << " " << a[7] << endl;
n++;
for (int j=1; j<8; j++)
a[j]=0;
}
return 0;
}
That what I have above is the code that I have thus far.
the Sum and the rest are left purposely uncompleted because that is still in the building phase.
Now, I need to make an expansion of euler' number,
This is supposed to make you use series like x[n] in order to divide a result into multiple parts and use functions to calculate the results and such.
According to it,
I need to find the specific part of the Maclaurin's Expansion and calculate it.
So the X in e=1+x+(1/2!)*x and so on is always 1
Giving us e=1+1+1/2!+1/3!+1/n! to calculate
The program should calculate it in order of the N
so If N is 1 it will calculate only the corresponding factorial division part;
meaning that one part of the variable will hold the result of the calculation which will be x=1.00000000~ and the other will hold the actual sum up until now which is e=2.000000~
For N=2
x=1/2!, e=previous e+x
for N=3
x=1/3!, e=previous e+x
The maximum number of N is 29
each time the result is calculated, it needs to hold all the numbers after the dot into separate variables like x[1] x[2] x[3] until all the 30~35 digits of precision are filled with them.
so when printing out, in the case of N=2
x[0].x[1]x[2]x[3]~
should come out as
0.50000000000000000000
where x[0] should hold the value above the dot and x[1~3] would be holding the rest in 5 digits each.
Well yeah Sorry if my explanation sucks but This is what its asking.
All the arrays must be in Int and I cannot use others
And I cant use bigint as it defeats the purpose
The other problem I have is, while doing the operations, it goes well till the 7th.
Starting from the 8th and so on It wont continue without giving me negative numbers.
for N=8
It should be 00002480158730158730158730.
Instead I get 00002 48015 -19220 -41904 30331 53015 -19220
That is obviously due to int's limit and since at that part it does
1936000000%40320
in order to get a[3]'s value which then is 35200 which is then multiplied by 100000
giving us a 3520000000/40320, though the value of a[3] exceeds the limit of integer, any way to fix this?
I cannot use doubles or Bigints for this so if anyone has a workaround for this, it would be appreciated.
You cannot use floating point or bigint, but what about other compiler intrinsic integral types like long long, unsigned long long, etc.? To make it explicit you could use <stdint.h>'s int64_t and uint64_t (or <cstdint>'s std::int64_t and std::uint64_t, though this header is not officially standard yet but is supported on many compilers).
I don't know if this is of any use, but you can find the code I wrote to calculate Euler's number here: http://41j.com/blog/2011/10/program-for-calculating-e/
32bit int limits fact to 11!
so you have to store all the above facts divided by some number
12!/10000
13!/10000
when it does not fit anymore use 10000^2 and so on
when using the division result is just shifted to next four decimals ... (as i assumed was firstly intended)
of course you do not divide 1/n!
on integers that will be zero instead divide 10000
but that limits the n! to only 9999 so if you want more add zeroes everywhere and the result are decimals
also i think there can be some overflow so you should also carry on to upper digits