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.
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.
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;
}
Related
I have C++ code here:
#include <iostream>
#include <cmath>
#include <time.h>
using namespace std;
int main()
{
double n,x;
cin>>n>>x;
double b=1,c=0.0;
for (int i=1;i<=n;i++){
x=pow(x,i);
x=x*pow((-1),(i+1));
cout<<x<<endl;
b=i;
c=c+x/b;
}
cout<<c<<endl;
return 0;
}
I am creating this to calculate x^1-x^2/2+x^3/3-.....+(-1)^(n-1)*(x^n)/n. The user inputs n. The problem appears to be in this line: x=x*pow((-1),(i+1));.
I am creating this to calculate x^1 - x^2/2 + x^3/3 - ... + (-1)^(n-1)*(x^n)/n.
That seems to be the Maclaurin series of ln(1 + x), but it's not what the posted code evaluates, though:
for (int i=1;i<=n;i++)
{
x = pow(x,i);
// ^ This is updated at each iteration! It should be const.
x = x * pow((-1),(i+1));
// ^^^^^^^^^^^^^^^ Please don't (see later).
b=i;
c=c+x/b;
// ^ Okish, but why not use i directly?
}
At the very least, a variable different from x should be introduced to store the results of the powers.
The use of pow((-1),(i+1)) to generate the simple sequence {1, -1, 1, -1, ...} is also questionable, if not prone to rounding errors. I'll show two different ways to accomplish the same task.
// Evaluates the Mclaurin series of ln(1 + x) using n terms.
// Noting that (e.g. with n == 4):
// p(4) = x -x^2 / 2 + x^3 / 3 - x^4 / 4
// p(4) = x - x*x/2 + x*x*x/3 - x*x*x*x/4
// p(4) = k(1) -x*k(1)/2 + x*x*x/3 - x*x*x*x/4 k(1) = x
// p(4) = k(1) -x*k(1)/2 -x*k(2)/3 - x*x*x*x/4 k(2) = -x*k(1)
// p(4) = k(1) -x*k(1)/2 -x*k(2)/3 -x*k(3)/4 k(3) = -x*k(2)
// Preconditions: n >= 1 and -1 < x <= 1
double fn(int n, double x)
{
double k{ x };
double sum{ x };
for (int i{ 2 }; i <= n; ++i)
{
k *= -x;
sum += k / i;
}
return sum;
}
Note that, in the interval of convergence, abs(k / i) tends to zero, while outside it grows. Eventually, due to the limited precision of floating-point types like double, sum += k/i won't change the value of sum.
Another approach may be based on Horner's rule.
// Evaluates the Mclaurin series of ln(1 + x) using n terms.
// Applying Horner's rule:
// p(4) = x -x^2 / 2 + x^3 / 3 - x^4 / 4
// = x*(1 + x*(-1/2 + x*(1/3 + x*(-1/4))))
// = x*(1 + x*(-1/2 + x*( 1/3 + x*k(4) ))) k(4) = 1/4
// = x*(1 + x*( -1/2 + x*k(3) )) k(3) = 1/3 + x*k(4)
// = x*( 1 + x*k(2) ) k(2) = -1/2 + x*k(3)
// = x * k(1) k(1) = 1 + x*k(2)
// Preconditions: n >= 1 and -1 < x <= 1
double fn(int n, double x)
{
double sign{ n % 2 == 0? -1.0 : 1.0 };
double k{ sign / n };
while ( --n > 0 )
{
sign = -sign;
k = sign / n + x * k;
}
return k * x;
}
This question already has an answer here:
Dividing two integers to produce a float result [duplicate]
(1 answer)
Closed 2 years ago.
// PI = 4 - (4/3) + (4/5) - (4/7) ... for 100 first statements
#include <iostream>
#include <conio.h>
using namespace std;
int main() {
double PI = 0.0;
int a = 1;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 1) {
PI += double(4 / a);
}
else {
PI -= double(4 / a);
}
a += 2;
}
cout << "PI Number is : " << PI;
cout << endl;
return 0;
}
I tried this code in visual studio 2015 to give me the answer of PI number value but it returns "PI Number is : 3" and I want it to return a float or a double number.
What should I do?
In double(4 / a), the 4 / a part evaluates to an integer and it is already truncated by the time you cast it to double. What you want to do is 4.0 / a instead, and no need for an explicit cast.
4 / a is an integer division and your conversion double(…) happens after that division, so the result will never have something after the decimal point. e.g. 4/5 results in 0.
You need to change 4 from an integer to a double 4.
The issue in your code is when it's computing the value:
double PI = 0.0;
int a = 1;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 1) {
PI += double(4 / a);
}
else {
PI -= double(4 / a);
}
a += 2;
}
You shouldn't do double(4 / a) but rather (double)4 / a or 4.0 / a
double PI = 0.0;
int a = 1;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 1) {
PI += (double)4 / a;
}
else {
PI -= (double)4 / a;
}
a += 2;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm pretty new in coding and trying to write a sin progression for the uni
As a formula it looks like this:
So I tried to code it... And somehow, it calculates the radian but not the sinus... What is wrong?
#include "stdafx.h"
#include <iostream>
#include <math.h>
using namespace std;
double n, a;
int fakultaet(double a = 2 * n + 1)
{
if (a == 0)
return 1;
else
return (a * fakultaet(a - 1));
}
int _tmain(int argc, _TCHAR* argv[])
{
double sin, y, f; // sin = Sinus, y= angle, n=index
printf("please insert the angle \n");
scanf("%lf", &y);
double x = y * 3.14159265359 * 1 / 180; // x = radian measure
while (n < 5)
{
sin = pow(-1, n) * pow(x, 2 * n + 1) / fakultaet(a);
}
printf("The sinus is %lf\n", sin);
system("Pause");
return 0;
}
You are not incrementing the sin, or the n. Also hardcoding the entry value for the factorial is not good.
It should look more like this:
#include "stdafx.h"
#include <iostream>
#include <math.h>
using namespace std;
int fakultaet(double a)
{
if (a == 0)
return 1;
else
return (a * fakultaet(a - 1));
}
int main()
{
double sin = 0, y, f; // sin = Sinus, y= angle, n=index
printf("please insert the angle \n");
scanf("%lf", &y);
double x = y * 3.14159265359 * 1 / 180; // x = radian measure
for (int n = 0; n < 5; ++n)
{
sin += pow(-1, n) * pow(x, 2 * n + 1) / fakultaet(2 * n + 1);
}
printf("The sinus is %lf\n", sin);
system("Pause");
return 0;
}
I made several edits. I turned the factorial function:
int fakultaet(double a = 2 * n + 1)
into an non hardcoded version:
int fakultaet(double a)
Added the sin initialization:
double sin = 0
Changed your while loop:
while (n < 5)
Into a for which includes the increment that was missing as well:
for (int n = 0; n < 5; ++n)
Also turned the sin calculation:
sin = pow(-1, n) * pow(x, 2 * n + 1) / fakultaet(a);
Into one that sums:
sin += pow(-1, n) * pow(x, 2 * n + 1) / fakultaet(2 * n + 1);
You can get a neater and more efficient result by observing that
adjacent terms in the sum are related. We can express this as a recurrence:
T_n = - T_{n-1} x^2 /((2n+1) (2n))
T_0 = x
This is better since it avoids calls to pow and the need to make any explicit factorial calculations (fakultaet).
The code looks something like:
int main() {
...
double T = x;
double sin = T;
for(int i=1 ; i<5; ++i) {
T *= -(x*x) / ((2*i+1)*(2*i));
sin += T;
}
...
}
I am trying to implement my own square root function which gives square root's integral part only e.g. square root of 3 = 1.
I saw the method here and tried to implement the method
int mySqrt(int x)
{
int n = x;
x = pow(2, ceil(log(n) / log(2)) / 2);
int y=0;
while (y < x)
{
y = (x + n / x) / 2;
x = y;
}
return x;
}
The above method fails for input 8. Also, I don't get why it should work.
Also, I tried the method here
int mySqrt(int x)
{
if (x == 0) return 0;
int x0 = pow(2, (log(x) / log(2))/2) ;
int y = x0;
int diff = 10;
while (diff>0)
{
x0 = (x0 + x / x0) / 2; diff = y - x0;
y = x0;
if (diff<0) diff = diff * (-1);
}
return x0;
}
In this second way, for input 3 the loop continues ... indefinitely (x0 toggles between 1 and 2).
I am aware that both are essentially versions of Netwon's method but I can't figure out why they fail in certain cases and how could I make them work for all cases. I guess i have the correct logic in implementation. I debugged my code but still I can't find a way to make it work.
This one works for me:
uintmax_t zsqrt(uintmax_t x)
{
if(x==0) return 0;
uintmax_t yn = x; // The 'next' estimate
uintmax_t y = 0; // The result
uintmax_t yp; // The previous estimate
do{
yp = y;
y = yn;
yn = (y + x/y) >> 1; // Newton step
}while(yn ^ yp); // (yn != yp) shortcut for dumb compilers
return y;
}
returns floor(sqrt(x))
Instead of testing for 0 with a single estimate, test with 2 estimates.
When I was writing this, I noticed the result estimate would sometimes oscillate. This is because, if the exact result is a fraction, the algorithm could only jump between the two nearest values. So, terminating when the next estimate is the same as the previous will prevent an infinite loop.
Try this
int n,i;//n is the input number
i=0;
while(i<=n)
{
if((i*i)==n)
{
cout<<"The number has exact root : "<<i<<endl;
}
else if((i*i)>n)
{
cout<<"The integer part is "<<(i-1)<<endl;
}
i++;
}
Hope this helps.
You can try there C sqrt implementations :
// return the number that was multiplied by itself to reach N.
unsigned square_root_1(const unsigned num) {
unsigned a, b, c, d;
for (b = a = num, c = 1; a >>= 1; ++c);
for (c = 1 << (c & -2); c; c >>= 2) {
d = a + c;
a >>= 1;
if (b >= d)
b -= d, a += c;
}
return a;
}
// return the number that was multiplied by itself to reach N.
unsigned square_root_2(unsigned n){
unsigned a = n > 0, b;
if (n > 3)
for (a = n >> 1, b = (a + n / a) >> 1; b < a; a = b, b = (a + n / a) >> 1);
return a ;
}
Example of usage :
#include <assert.h>
int main(void){
unsigned num, res ;
num = 1847902954, res = square_root_1(num), assert(res == 42987);
num = 2, res = square_root_2(num), assert(res == 1);
num = 0, res = square_root_2(num), assert(res == 0);
}
Source
This question already has answers here:
The most efficient way to implement an integer based power function pow(int, int)
(21 answers)
Closed 8 years ago.
I've read that cmath calculates pow(a,b) by performing exp(b*log(a)). This should not be used when b is an integer, since it slows down calculations a lot. What alternatives are there when
calculating a lot of successive pow()s with the same constant a
it is known beforehand that b will definitely be an integer?
I am looking for fast alternatives which are efficient in these particular scenarios.
There are a number of faster alternatives I've collected over the years that typically rely on a recursive implementation of the function, and bit shifts to handle multiplication when warranted. The following provide functions tailored to integer, float and double. They come with the normal disclaimer: while faster not all possible test have been run and the user should validate input is sane before calling and on return... blah, blah, blah.. But, they are pretty darn useful:
I believe proper attribution goes to Geeks for Geeks Pow(x,n) as pointed out by blue moon. I had long since lost the links.. That looks like them. (minus a tweak or two).
/* Function to calculate x raised to the power y
Time Complexity: O(n)
Space Complexity: O(1)
Algorithmic Paradigm: Divide and conquer.
*/
int power1 (int x, unsigned int y)
{
if (y == 0)
return 1;
else if ((y % 2) == 0)
return power1 (x, y / 2) * power1 (x, y / 2);
else
return x * power1 (x, y / 2) * power1 (x, y / 2);
}
/* Function to calculate x raised to the power y in O(logn)
Time Complexity of optimized solution: O(logn)
*/
int power2 (int x, unsigned int y)
{
int temp;
if (y == 0)
return 1;
temp = power2 (x, y / 2);
if ((y % 2) == 0)
return temp * temp;
else
return x * temp * temp;
}
/* Extended version of power function that can work
for float x and negative y
*/
float powerf (float x, int y)
{
float temp;
if (y == 0)
return 1;
temp = powerf (x, y / 2);
if ((y % 2) == 0) {
return temp * temp;
} else {
if (y > 0)
return x * temp * temp;
else
return (temp * temp) / x;
}
}
/* Extended version of power function that can work
for double x and negative y
*/
double powerd (double x, int y)
{
double temp;
if (y == 0)
return 1;
temp = powerd (x, y / 2);
if ((y % 2) == 0) {
return temp * temp;
} else {
if (y > 0)
return x * temp * temp;
else
return (temp * temp) / x;
}
}
Non-recursive non-floating point answer
Replace uintmax_t/intmax_t with the type of your desire. Overflow not detected.
uintmax_t powjuu(unsigned x, unsigned y) {
uintmax_t z = 1;
uintmax_t base = x;
while (y) {
if (y & 1) { // or y%2
z *= base;
}
y >>= 1; // or y /= 2
base *= base;
}
return z;
}
intmax_t powjii(int x, int y) {
if (y < 0) {
switch (x) {
case 0:
return INTMAX_MAX;
case 1:
return 1;
case -1:
return y % 2 ? -1 : 1;
}
return 0;
}
intmax_t z = 1;
intmax_t base = x;
while (y) {
if (y & 1) {
z *= base;
}
y >>= 1;
base *= base;
}
return z;
}
You may want to check this. It's a fast algorithm to replace the pow function.