I have a program which must print perfect square roots of all integer numbers within an interval. Now I want to do that for n-the root.
Here's what I've done, but I'm stuck at fmod.
#include <iostream>
#include <math.h>
using namespace std;
int nroot(int, int);
int main()
{
int p, min, max,i;
double q;
cout << "enter min and max of the interval \n";
cin >> min;
cin >> max;
cout << "\n Enter the n-th root \n";
cin >> p;
i = min;
while (i <= max)
{
if (fmod((nroot(i, p)), 1.0) == 0)
{
cout << nroot(i, p);
}
i++;
}
return 0;
}
int nroot (int i, int p){
float q;
q = (pow(i, (1.0 / p)));
return q;
}
You may want to tackle this in the opposite direction. Rather than taking the nth root of every value in the interval to see if the nth root is an integer, instead take the nth root of the bounds of the interval, and step in terms of the roots:
// Assume 'min' and 'max' set as above in your original program.
// Assume 'p' holds which root we're taking (ie. p = 3 means cube root)
int min_root = int( floor( pow( min, 1. / p ) ) );
int max_root = int( ceil ( pow( max, 1. / p ) ) );
for (int root = min_root; root <= max_root; root++)
{
int raised = int( pow( root, p ) );
if (raised >= min && raised <= max)
cout << root << endl;
}
The additional test inside the for loop is to handle cases where min or max land directly on a root, or just to the side of a root.
You can remove the test and computation from the loop by recognizing that raised is only needed at the boundaries of the loop. This version, while slightly more complex looking, implements that observation:
// Assume 'min' and 'max' set as above in your original program.
// Assume 'p' holds which root we're taking (ie. p = 3 means cube root)
int min_root = int( floor( pow( min, 1. / p ) ) );
int max_root = int( ceil ( pow( max, 1. / p ) ) );
if ( int( pow( min_root, p ) ) < min )
min_root++;
if ( int( pow( max_root, p ) ) > max )
max_root--;
for (int root = min_root; root <= max_root; root++)
cout << root << endl;
If you're really concerned about performance (which I suspect you are not in this case), you can replace int( pow( ..., p ) ) with code that computes the nth power entirely with integer arithmetic. That seems like overkill, though.
Exact equality test for floating numbers might not work as you expect. It's better to compare with some small number:
float t = nroot(i, p);
if (fabs(t - rintf(t)) <= 0.00000001)
{
cout << t << endl;
}
Even in this case you aren't guaranteed to get correct results for all values of min, max and p. All depends on this small number and precision you represent numbers. You might consider longer floating types like "double" and "long double".
Related
I am trying to count series of: 1/2 + 1/3 + 1/4 + 1/5 + ...
But I had problem with my output:
Insert how many series's number will be counted : 3 // I am input 3
Total = 1 // This is the problem, the output should shown = 1.8333
My program
#include <iostream>
#include <math.h>
using namespace std;
int recursion ( int n );
int main ()
{
int n;
cout << "Insert how many number will be counted : ";cin >> n;
cout << "Total = " << recursion(n);
}
int recursion (int a)
{
int result;
if ( a >= 1 )
{
result = 1;
}
else
{
result = ( pow ( a , -1 ) + recursion ( pow ( ( a - 1 ) , -1 ) ) );
}
return (result);
}
As others have said, use floating point types, such as double or float.
In integer division, 1/3 == 0.
Here's an iterative example:
const unsigned int NUMBER_OF_TERMS = 100;
double result = 0.0;
double denominator = 2.0;
for (unsigned int i = 0; i < NUMBER_OF_TERMS; ++i)
{
result = result + 1.0 / denominator;
denominator = denomenator + 1.0;
}
Your code should use floating point constants (with decimal points) and floating point variables (of type double or float).
Edit 1: Basic recursion
In some cases of recursion, thinking of the solution backwards may help the implementation.
For example, the series starts with 1.0/2.0. However, since the sum operation doesn't depend on order, we can start with 1.0/5.0 and work backwards:
result = 1.0/5.0 + 1.0/4.0 + 1.0/3.0 + 1.0/2.0
This allows the denominator to be used as the condition for ending the recursion.
double recursive_sum(double denominator)
{
if (denominator < 2)
{
return 0.0;
}
return recursive_sum(denominator - 1.0)
+ 1.0 / denominator;
}
I am testing recursion, however when I have an array with more than 150000 elements segmentation error occurs. What can be the problem?
#include <iostream>
using namespace std;
void init ( float a[] , long int n );
float standard ( float a[] , long int n , long int i );
int main()
{
long int n = 1000000;
float *a = new float[n];
init ( a , n );
cout.precision ( 30 );
cout << "I got here." << endl;
cout << "Standard sum= " << standard ( a , 0 , n - 1 ) << endl;
delete [] a;
return 0;
}
void init ( float a[] , long int n )
{
for (long int i = 0 ; i < n ; i++ )
{
a[i] = 1. / ( i + 1. );
}
}
float standard ( float a[] , long int i , long int n )
{
if ( i <= n )
return a[i] + standard ( a , i + 1 , n );
return 0;
}
As an expansion to MicroVirus' correct answer, here is an example of tail recursive version of your algorithm:
float standard_recursion(float* a, long i, long n, long result) {
if(i > n)
return result;
return standard_recursion(a, i + 1, n, result + a[i]);
}
float standard(float* a, long i, long n ) {
return standard_recursion(a, i, n, 0);
}
This should run if the compiler does tail call optimization (I tested on g++ -O2). However, since the functionality depends on the compiler optimization, I would recommend to avoid deep recursion entirely and opt for iterative solution.
You are most likely running out of stack space in your recursive function standard, which recurses with a depth of n, and tail-call optimisation is probably not enabled here.
So, to answer the question in your title: Yes, there is a limit to recursion, and usually it's the available stack space.
Probably you are out of memory on heap. Also if you got 16bit int, there could be a problem with iterations. Better use int32_t i instead of int i. Same with n.
I have this very simple function that checks the value of (N^N-1)^(N-2):
int main() {
// Declare Variables
double n;
double answer;
// Function
cout << "Please enter a double number >= 3: ";
cin >> n;
answer = pow(n,(n-1)*(n-2));
cout << "n to the n-1) to the n-2 for doubles is " << answer << endl;
}
Based on this formula, it is evident it will reach to infinity, but I am curious until what number/value of n would it hit infinity? Using a loop seems extremely inefficient, but that's all I can think of. Basically, creating a loop that says let n be a number between 1 - 100, iterate until n == inf
Is there a more efficient approach to this problem?
I think you are approaching this the wrong way.
Let : F(N) be the function (N^(N-1))(N-2)
Now you actually know whats the largest number that could be stored in a double type variable
is 0x 7ff0 0000 0000 0000 Double Precision
So now you have F(N) = max_double
just solve for X now.
Does this answer your question?
Two things: the first is that (N^(N-1))^(N-2)) can be written as N^((N-1)*(N-2)). So this would remove one pow call making your code faster.
pow(n, (n-1)*(n-2));
The second is that to know what practical limits you hit, testing all N will literally take a fraction of a second, so there really is no reason to find another practical way.
You could compute it by hand knowing variable size limits and all, but testing it is definitely faster. An example for code (C++11, since I use std::isinf):
#include <iostream>
#include <cmath>
#include <iomanip>
int main() {
double N = 1.0, diff = 10.0;
const unsigned digits = 10;
unsigned counter = digits;
while ( true ) {
double X = std::pow( N, (N-1.0) * (N-2.0) );
if ( std::isinf(X) ) {
--counter;
if ( !counter ) {
std::cout << std::setprecision(digits) << N << "\n";
break;
}
N -= diff;
diff /= 10;
}
N += diff;
}
return 0;
}
This example takes less than a millisecond on my computer, and prints 17.28894235
I found many similar topics but none of them gives me clear explanation.
I have to write program which calculates Pi squared to n digits using this taylor series:
π^2 = 12 ( 1/1^2 - 1/2^2 + 1/3^2 - 1/4^2 + ... )
I wrote this:
#include <iostream>
#include <math.h>
using namespace std;
int main() {
int n;
cout << "How many digits?" << endl;
cin >> n;
long double Pi2 = 0;
int i = 1;
while( precision is less than n ) {
if ((i%2) == 1) {
Pi2 += 1/pow(i,2);
i+=1;
}
else {
Pi2 -= 1/pow(i,2);
i+=1;
}
}
Pi2 *= 12;
cout << Pi2 << endl;
return 0;
}
and I have no idea what to write in while() ? When should this loop stop?
If You know the required precision, You can calculate the right value for the maximum value for n before You start the loop.
Second thing: start with the most less number if You start adding all delta values.
Similar to this
int ndigits;
cout << "How many digits?" << endl;
cin >> ndigits;
int n = int( pow( double(10), double(ndigits)/2 ) + 0.5 );
long double Pi2 = 0;
int i = 1;
for( int i=n; i>0; --i )
{
if ((i%2) == 1) {
Pi2 += 1/pow(long double(i),2);
}
else {
Pi2 -= 1/pow(long double(i),2);
}
}
Pi2 *= 12;
A method to consider is using ndigits to create an 'epsilon' value.
Let's assume ndigits is 3. That give an epsilon of 0.0001
if the difference between your value from the previous iteration, and the current iteration is less than 0.0001, then you can assume you have the value you are after, and terminate the while loop.
A warning though. Doubles and long doubles have an upper limit on the number of digits they can hold accurately.
I'm doing another C++ exercise. I have to calculate the value of pi from the infinite series:
pi=4 - 4/3 + 4/5 – 4/7 + 4/9 -4/11+ . . .
The program has to print the approximate value of pi after each of the first 1,000 terms of this series.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
double pi=0.0;
int counter=1;
for (int i=1;;i+=2)//infinite loop, should "break" when pi=3.14159
{
double a=4.0;
double b=0.0;
b=a/static_cast<double>(i);
if(counter%2==0)
pi-=b;
else
pi+=b;
if(i%1000==0)//should print pi value after 1000 terms,but it doesn't
cout<<pi<<endl;
if(pi==3.14159)//this if statement doesn't work as well
break;
counter++;
}
return 0;
}
It compiles without errors and warnings, but only the empty console window appears after execution. If I remove line” if(i%1000==0)” , I can see it does run and print every pi value, but it doesn’t stop, which means the second if statement doesn’t work either. I’m not sure what else to do. I’m assuming it is probably a simple logical error.
Well, i % 1000 will never = 0, as your counter runs from i = 1, then in increments of 2. Hence, i is always odd, and will never be a multiple of 1000.
The reason it never terminates is that the algorithm doesn't converge to exactly 3.14157 - it'll be a higher precision either under or over approximation. You want to say "When within a given delta of 3.14157", so write
if (fabs(pi - 3.14157) < 0.001)
break
or something similar, for however "close" you want to get before you stop.
Since you start i at 1 and increment by 2, i is always an odd number, so i % 1000 will never be 0.
you have more than one problem:
A. i%1000==0 will never be true because you're iterating only odd numbers.
B. pi==3.14159 : you cannot compare double values just like that because the way floating point numbers are represented (you can read about it here in another question). in order for it to work you should compare the values in another way - one way is to subtract them from each other and check that the absolute result is lower than 0.0000001.
You have floating point precision issues. Try if(abs(pi - 3.14159) < 0.000005).
i%1000 will never be 0 because i is always odd.
Shouldn't it be:
if (counter%1000==0)
i starts at 1 and then increments by 2. Therefore i is always odd and will never be a multiple of 1000, which is why if (i % 1000 == 0) never passes.
Directly comparing floats doesn't work, due to floating precision issues. You will need to compare that the difference between the values is close enough.
pi=4 - 4/3 + 4/5 – 4/7 + 4/9 -4/11 + ...
Generalising
pi = Σi=0∞ (-1)i 4 / (2i+1)
Which gives us a cleaner approach to each term; the i'th term is given by:
double term = pow(-1,i%2) * 4 / (2*i+1);
where i=0,1,2,...,N
So, our loop can be fairly simple, given some number of iterations N
int N=2000;
double pi=0;
for(int i=0; i<N; i++)
{
double term = pow(-1,i%2) * 4 / (2*(double)i+1);
pi += term;
cout << i << "\t" << pi <<endl;
}
Your original question stated "The program has to print the approximate value of pi after each of the first 1,000 terms of this series". This does not imply any need to check whether 3.14159 has been reached, so I have not included this here. The pow(-1,i%2) call is just to avoid if statements (which are slow) and prevent any complications with large i.
Be aware that after a number of iterations, the difference between the magnitude of pi and the magnitude of the correcting term (say -4/25) will be so small that it will go beyond the precision of a double, so you would need higher precision types to deal with it.
By default abs uses the abs macro which is for int. For doubles, use the cmath library.
#include <iostream>
#include <cmath>
int main()
{
double pi=0.0;
double a=4.0;
int i = 1;
for (i=1;;i+=2)
{
pi += (1 - 2 * ((i/2)%2)) * a/static_cast<double>(i);
if( std::abs(pi - 3.14159) < 0.000001 )
break;
if (i > 2000) //1k iterations
break;
}
std::cout<<pi<<std::endl;
return 0;
}
Here is the corrected code. I thought it may be helpful in the future if somebody has similar problem.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double pi=0.0;
int counter=1;
for (int i=1;;i+=2)
{
double a=4.0;
double b=0.0;
b=a/static_cast<double>(i);
if(counter%2==0)
pi-=b;
else
pi+=b;
if(counter%1000==0)
cout<<pi<<" "<<counter<<endl;
if (fabs(pi - 3.14159) < 0.000001)
break;
counter++;
}
cout<<pi;
return 0;
}
Here is a better one:
class pi_1000
{
public:
double doLeibniz( int i ) // Leibniz famous formula for pi, source: Calculus II :)
{
return ( ( pow( -1, i ) ) * 4 ) / ( ( 2 * i ) + 1 );
}
void piCalc()
{
double pi = 4;
int i;
cout << "\npi calculated each iteration from 1 to 1000\n"; //wording was a bit confusing.
//I wasn't sure which one is the right one: 0-1000 or each 1000th.
for( i = 1; i < 1000; i++ )
{
pi = pi + doLeibniz( i );
cout << fixed << setprecision( 5 ) << pi << "\t" << i + 1 << "\n";
}
pi = 4;
cout << "\npi calculated each 1000th iteration from 1 to 20000\n";
for( i = 1; i < 21000; i++ )
{
pi = pi + doLeibniz( i );
if( ( ( i - 1 ) % 1000 ) == 0 )
cout << fixed << setprecision( 5 ) << pi << "\t" << i - 1 << "\n";
}
}