-3

I've recently been given a problem by my teacher about some mathematical equation / formula called the arctanx formula. The question is:

According to the Arctanx(x) = x - ((x ^ 3) / 3) + ((x ^ 5) / 5) - ((x ^ 
7) / 7) + ...and π = 6 * arctanx(1 / sqrt(3)), Create function arctanx(x)
, and find pi when the last "number"(like this ((x ^ y) / y)) is right before
 and bigger than 10 ^ -6, or you can say that no "number" can be smaller than
that number without being smaller than 10 ^ -6.

I tried to code it out, but there is a bug in it.

# include<iostream>
# include<math.h>
using namespace std;
float arctanx() {
    long double pi = 3.1415926535897;
    int i = 0; // 0 = +, 1 = -
    float sum = 0;
    float lsum;
    for (int y = 1; y < pi; y += 2) {
        if (lsum > 0.000001) {
            if (i == 0) {
                lsum = pow(1 / sqrt(3), y) / y;
                sum += pow(1 / sqrt(3), y) / y;
                i++;
            } else if (i == 1) {
                lsum = pow(1 / sqrt(3), y) / y;
                sum -= pow(1 / sqrt(3), y) / y;
                i--;
            }
        } else {
            break;
        }
    }

    sum = sum * 6;
    return sum;

}

int main() {
    cout << arctanx();
    return 0;
}

It should have a output of some number not equal to zero, but I got 0 from running this.

andy zhang
  • 21
  • 6

2 Answers2

1

Your program has Undefined Behavior because you are using the uninitialized float lsum; in the comparison if (lsum > 0.000001). What probably happens in your case is that lsum happens to be less than or equal to 0.000001 and your for immediately breaks without doing anything causing your function to return 0 * 6 which is obviously 0.

DeviatioN
  • 340
  • 1
  • 3
  • 8
0

Create function arctanx(x)

The function defined in the posted code doesn't accept any parameter, it just uses the hardwired (and repeated) value 1 / sqrt(3) and tries to return an approximated value of π instead of the arctangent of x.

It also has undefined behavior, beeing lsum uninitialized (therefore having an indeterminate value) when it is first used in the comparison inside the loop.

Consider this implementation, but be advised that this particular polinomial expansion diverges for values of x greater than 1.

#include <iostream>
#include <iomanip>
#include <cmath>

double arctanx(double x);

int main()
{
    double pi = 6.0 * arctanx(1.0 / std::sqrt(3));

    std::cout << std::setprecision(8) << pi << '\n';
}

double arctanx(double x)
{
    // You can take advantage of a running power, instad of calculating
    // pow(x, i) at every iteration
    double sq_x = x * x;
    double pow_x = x * sq_x;
    double err = 1e-6;

    // Instead of keeping track of the alternating sign, you can use
    // two separate partial sums
    double sum_pos_term = x;
    double sum_neg_term = 0.0;
    for (int i = 3; i < 33; i += 2)  // <- Limit the number of iterations
    {
        if (pow_x < err * i)
            break;
        sum_neg_term += pow_x / i;
        i += 2;
        pow_x *= sq_x;
        if (pow_x < err * i)
            break;
        sum_pos_term += pow_x / i;
        pow_x *= sq_x;
    }
    return sum_pos_term - sum_neg_term;
}
Bob__
  • 12,361
  • 3
  • 28
  • 42