C++ always returns -inf when calculating cosine - c++

I am attempting to write a function that takes a value x and calculates the cos x by the series expansion, I'm always getting -inf, indifferent which value is read in.
#include <iostream>
#include <math.h>
#include <iomanip>
using namespace std;
int fac(int n){
return n == 0 || n == 1 ? 1 : n * fac(n-1);
}
int main(){
double eps = 1e-15;
double x;
cin >> x;
long double ak = 1, sn = 0;
for(int k=1; abs(ak) > eps * abs(sn); k++){
double sgn = k % 2 == 0 ? 1 : -1;
sn += ak;
ak = sgn * pow(x, 2 * k) / fac(2*k);
}
cout << setprecision(4) << setw(5) << "x" << setprecision(15) << setw(20) << "cos x" << endl;
cout << setprecision(4) << setw(5)<< x << " " << setprecision(15) << setw(20) << sn << endl;
cout << setw(26) << cos(x) << endl;
return 0;
}
I debugged the code and at a certain point ak gets -inf. But why?

Related

A tabulation program on a given interval [a;b] with step c

I developed a program to tabulate a given interval [a;b] with a step of c, and also find its largest and smallest value on this interval. I'm not sure if I have it right, so I wanted some advice. This code has a picture with a task condition.enter image description here
In the process of solving the given problem, apply the loop operator with a prerequisite. In the process of implementing the given task, assume that the argument of the function is identified as x, and the identifier of the variable responsible for the value of the function is y.
#include <iostream>
#include <math.h>
#include <clocale>
#define _USE_MATH_DEFINES
#include <iomanip>
#include<climits>
using namespace std;
int main(){
setlocale(LC_CTYPE, "");
double x, y, a, b, c;
double max, min, max_y, min_y;
max = -INT_MAX;
min = INT_MAX;
cout << "\n a:";
cin >> a;
cout << "\n b:";
cin >> b;
cout << "\n c:";
cin >> c;
cout << "\n a = " << a;
cout << " b = " << b;
cout << " c = " << c;
y = a;
while(y <= b){
if(y > 1) x = sin(sqrt(y + log(y)));
if((0 <= y) && (y <= 1)) x = M_PI + pow(cos(y + 1.2), 2);
if(y < 0) x = y * log10(pow(y,2) +2) + M_PI;
if(x > max){
max = x;
max_y = y;
}
if(x < min){
min = x;
min_y = y;
}
cout << "\n x = " << setw(8) << x << " y = " << setw(8) << y;
y += c;
}
cout << "\n The largest value in the given interval is" << max << " at y = " << max_y << "\n";
cout << "\n The smallest value in the given interval is" << min << " at y = " << min_y << "\n";
return 0;
}
When entering the values a,b,c into the console, our program should tabulate the function (output to the console) and find the smallest and largest value in the interval. I have the program working, but I'm not sure if it's correct. I would like to hear some advice
Added small updates:
Looks good overal
#include <iostream>
#include <cmath> //math.h == cmath
#include <clocale>
#define _USE_MATH_DEFINES
#include <iomanip>
#include<climits>
using namespace std;
void tabulate(double from, double to, double step)
{
double max, min, max_y, min_y, x = 0;
max = from; //they all start at 'from' anyway, its always best to set the max and min to first element of the array you're going through. They get overwritten anyway.
min = from;
for(double y = from; y < to; y += step)
{
if(y > 1) x = sin(sqrt(y + log(y)));
if((0 <= y) && (y <= 1)) x = M_PI + pow(cos(y + 1.2), 2);
if(y < 0) x = y * log10(pow(y,2) +2) + M_PI;
if(x > max){
max = x;
max_y = y;
}
if(x < min){
min = x;
min_y = y;
}
cout << " x = " << setw(8) << x << " y = " << setw(8) << y << endl;
}
cout << "The largest value in the given interval is " << max << " at y = " << max_y << endl;
cout << "The smallest value in the given interval is " << min << " at y = " << min_y << endl;
}
int main(){
setlocale(LC_CTYPE, "");
double a,b,c;
cout << "a: ";
cin >> a;
cout << "b: ";
cin >> b;
cout << "c: ";
cin >> c;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
tabulate(a,b,c);
return 0;
}

Why do I keep getting zero and nan for these variables?

Here is my code, for n and m, I consistently get 0 for n and nan for m, and I do not know why. I have tried everything I could, but n always shows 0 whilst m is always nan.
#include <iostream>
#include <iomanip>
#include <math.h>
#include <complex>
using namespace std;
int main()
{
float a, b, c, root1, root2, n, m ;
cout << "Please input values for a, b and c to represent the variables in equation : ax^2 + bx + c" << endl; // Dont know how to raise 2 instead of using ^2
cin >> a >> b >> c;
const float d = (b * b) - (4 * a * c);
cout << "Determinant is equal to " << d << endl;
cout << setprecision(3); // to set number of decimal places
n = b / 2 * a;
m = sqrt(d) / 2 * a;
if (d > 0) {
root1 = (-b + sqrt(d)) / (2.0 * a); // positive root
root2 = (-b - sqrt(d)) / (2.0 * a); // negative root
cout << "Determinant is greater than zero, therefore the equation has two real roots, which are " << root1 << " and " << root2 << endl;
}
else if (d < 0) {
cout << "Determinant is less than zero, therefore there would be two imaginary roots: " << n << " + " << m << "i ";
cout << "and " << n << " - " << m << "i" << endl;
}
}
you have to put parenthesis.
n = b / (2 * a);
m = sqrt(d) / (2 * a);
If the d is negative, you should first convert it to a non-negative number before feed it into sqrt(). Remember C/C++ does not equal to math language.
My quick fix:
#include <complex>
#include <iomanip>
#include <iostream>
#include <math.h>
using namespace std;
int main() {
float a, b, c, root1, root2, n, m;
cout << "Please input values for a, b and c to represent the variables in equation : ax^2 + bx + c " << endl; // Dont know how to raise 2 instead of using ^2
cin >> a >> b >> c;
const float d = (b * b) - (4 * a * c);
cout << "Determinant is equal to " << d << endl;
cout << setprecision(3); // to set number of decimal places
n = b / (2 * a);
if (d > 0) {
m = sqrt(d) / (2 * a);
root1 = (-b + sqrt(d)) / (2.0 * a); // positive root
root2 = (-b - sqrt(d)) / (2.0 * a); // negative root
cout << "Determinant is greater than zero, therefore the equation has two "
"real roots, which are "
<< root1 << " and " << root2 << endl;
} else if (d < 0) {
m = sqrt(-d) / (2 * a);
cout << "Determinant is less than zero, therefore there would be two "
"imaginary roots: "
<< n << " + " << m << "*i ";
cout << "and " << n << " - " << m << "*i" << endl;
}
}
A reference to sqrt() function:
http://www.cplusplus.com/reference/cmath/sqrt/
You will need to make some changes to get the correct answers for all cases First, you need to include the case of zero determinant which produces two identical real roots. You will need to calculate m with -d in the third case, and you have to make sure to change its sign into positive sign if necessary. For more aesthetic results, you can include special cases to omit n if it equals 0, and m if it equals 1.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
float a, b, c, root1, root2, n, m;
cout << "Please input values for a, b and c to represent the variables in equation : ax^2 + bx + c" << endl;
cin >> a >> b >> c;
const float d = b * b - 4 * a * c;
cout << "Determinant is equal to " << d << endl;
cout << setprecision(3); // to set number of decimal places
if (d > 0)
{
root1 = (-b + sqrt(d)) / 2 / a;
root2 = (-b - sqrt(d)) / 2 / a;
cout << "Determinant is greater than zero, therefore the equation has two real roots, which are " << root1 << " and " << root2 << endl;
}
else if (d == 0)
{
root1 = -b / 2 / a;
cout << "Determinant is zero, therefore the equation has two identical real roots, which both are " << root1 << endl;
}
else
{
n = -b / 2 / a;
m = sqrt(-d) / 2 / a;
if (m < 0)
m *= -1;
if (n == 0)
{
if (m == 1)
cout << "Determinant is less than zero, therefore there would be two imaginary roots: i and -i" << endl;
else
cout << "Determinant is less than zero, therefore there would be two imaginary roots: " << m << "i and -" << m << "i" << endl;
}
else
{
if (m == 1)
cout << "Determinant is less than zero, therefore there would be two imaginary roots: " << n << " + " << "i and " << n << " - " << "i" << endl;
else
cout << "Determinant is less than zero, therefore there would be two imaginary roots: " << n << " + " << m << "i and " << n << " - " << m << "i" << endl;
}
}
}

Calculation after the for loop is incorrect (C++)

The code I am currently working on is a random walker. The code represents a person taking a step in any random direction (up,down,left,right), then the new location is printed out respectively. In the beginning the user is prompted to enter any amount of steps or how many times the loop should be iterated. The goal of the code is to calculate the squared distance between (0,0)initial and (x,y)final. The distance should be equal to (xx)+(yy) because the initial position that would normally be subtracted is (0,0). The issue or semantic issue I am running into is with the distance calculation. The calculation is not always using the correct x or y value. For example if the final location was (0,-4), somehow x = -1, therefore the distance equals 17 instead of 16. This first example is in image 1. Image 2 is another run for the code. Any help or tips would be greatly appreciated, here is the code:
#include <iostream>
#include <stdlib.h>
#include <ctime>
#include <cmath>
using namespace std;
int main(){
int N;
cout << "Please enter N amount of steps, and for NetBeans users press
'enter' twice." << endl;
cin >> N;
cout << "% RandomWalker " << N << endl;;
int r;
srand( time(0));
int x = 0;
int y = 0;
for(int i = 0; i <= N; i++) {
cout << "(" << x << ", " << y << ")" << endl;
r=rand()%4;
if (r == 0 )
x++;
else if (r == 1 )
x--;
else if (r == 2 )
y++;
else if (r == 3 )
y--;
}
int d = (x*x)+(y*y);
cout << "the distance equals: " << d << endl;
cout << endl;
cout << "x equals before: "<< x << endl;
x = (pow(x,2));
cout << "x equals after squaring: "<< x << endl;
cout << endl;
cout <<"y equals before: " << y << endl;
y = (pow(y,2));
int sum = x + y;
cout <<"y equals after squaring: " << y << endl;
cout << endl;
cout << "x+y after squaring equals: " << sum << endl;
}
for(int i = 0; i <= N; i++)
Since you are starting from 0, the condition should be i < N.
Next issue, is int d = (x*x)+(y*y); The distance formula is
So the initialization should be
int d = sqrt((x * x) + (y * y));
Also what is the point of squaring the x and y values at the end?
You are printing the position BEFORE it is changed based on the value of r. So the last value that's printed out is not the actual final value of x and y, but the one of one step earlier. That's why you're getting unexpected distance.
Sorry for the delayed response, I figured out what I had to do. The object of the assignment was to print out each location and find the squared distance at the end of the loop. Here was the solution for anyone interested.
#include <iostream>
#include <stdlib.h>
#include <ctime>
#include <cmath>
using namespace std;
int main(){
int N;
cout << "Please enter N amount of steps, and for NetBeans users press
'enter' twice." << endl;
cin >> N;
cout << "% RandomWalker " << N << endl;;
int r;
srand( time(0));
int x = 0;
int y = 0;
cout << "(" << x << ", " << y << ")" << endl;
for(int i = 1; i <= N; i++) {
r=rand()%4;
if (r == 0 )
x++;
else if (r == 1 )
x--;
else if (r == 2 )
y++;
else if (r == 3 )
y--;
cout << "(" << x << ", " << y << ")" << endl;
}
x = (pow(x,2));
y = (pow(y,2));
int squaredDistance = x + y;
cout << "The squared distance is " << squaredDistance << endl;
}

Issue with Box Muller Transform when implementing a Normal Distribution PRNG

Using a Linear Congruent Generator I am able to create two independent Pseudo-Random number sequences which are uniformly distributed. I am trying to alter my program to allow it to use these sequences and perform a Box-Muller transform to change them into a normally distributed set.
The issue I am having however is that my new "normally distributed random number" (Z) is always equal to zero regardless of the input seed values for the two uniform sequences.
Any tips would be gratefully appreciated.
Many Thanks
#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
#define M 4294967295
unsigned long get_rand(unsigned long x) //establishing function to generate random numbers
{
unsigned long a = 2269477;
unsigned long b = 1; //Values taken from wikipedia for Linear Congruence Method
unsigned long m = M;
unsigned long y;
y = (a * x + b) % m;
return y;
}
unsigned long get_normal(unsigned long x1, unsigned long x2)
{
unsigned long R;
unsigned long phi;
unsigned long u;
R = sqrt(-2 * log(x1)); //Box-Muller Transform
phi = (2 * M_PI*x2);
u = R*cos(phi);
return u;
}
double u1, u2, Z;
double bin0 = 0;
double bin1 = 0;
double bin2 = 0; //Variables used to store frequency of each number range
double bin3 = 0;
double bin4 = 0;
double bin5 = 0;
double bin6 = 0;
double bin7 = 0;
double bin8 = 0;
double bin9 = 0;
int main() {
double seed1,seed2;
cout << "Please enter seed values " << endl;
cin >> seed1;
cout << "\n";
cin >> seed2;
double x;
cout << "Please enter how many random numbers you want " << endl;
cin >> x;
cout << endl;
cout << "Random Numbers generated shown below: " << endl;
for (int i = 0; i < x; i++) //generate as many random numbers as the user has asked for
{
seed1 = get_rand(seed1);
seed2 = get_rand(seed2);
u1 = (double(seed1) / M); //changing to double and dividing by 'M' gets all values between 0 and 1
cout <<"U1 = " << u1 << endl; //type conversion to prevent integer rounding in division
u2 = (double(seed2) / M);
cout << "U2 = " << u2 << endl;
Z = get_normal(u1, u2);
cout <<"Z = " << Z << endl;
if (Z >= 0.0 && Z <= 0.1)
{ //checking for which intervals each random number falls into
bin0++; //if a number falls into this interval, increment the counter by 1 each time
}
else if (Z > 0.1 && Z <= 0.2) //if it doesnt fall into first interval, it will check the next interval, and so on...
{
bin1++;
}
else if (Z > 0.2 && Z <= 0.3)
{
bin2++;
}
else if (Z > 0.3 && Z <= 0.4)
{
bin3++;
}
else if (Z > 0.4 && Z <= 0.5)
{
bin4++;
}
else if (Z > 0.5 && Z <= 0.6)
{
bin5++;
}
else if (Z > 0.6 && Z <= 0.7)
{
bin6++;
}
else if (Z > 0.7 && Z <= 0.8)
{
bin7++;
}
else if (Z > 0.8 && Z <= 0.9)
{
bin8++;
}
else if (Z > 0.9 && Z <= 1.0)
{
bin9++;
}
}
double binTotal = bin0 + bin1 + bin2 + bin3 + bin4 + bin5 + bin6 + bin7 + bin8 + bin9;
cout << endl;
int bin0Percent = (bin0 / binTotal) * 100; //working out a percentage
cout << " Number of values in range 0.0-0.1: " << bin0 << endl; //output screen for each interval
cout << " Percentage of values in this interval: " << bin0Percent << "%" << endl;
cout << endl;
int bin1Percent = (bin1 / binTotal) * 100;
cout << " Number of values in range 0.1-0.2: " << bin1 << endl;
cout << " Percentage of values in this interval: " << bin1Percent << "%" << endl;
cout << endl;
int bin2Percent = (bin2 / binTotal) * 100;
cout << " Number of values in range 0.2-0.3: " << bin2 << endl;
cout << " Percentage of values in this interval: " << bin2Percent << "%" << endl;
cout << endl;
int bin3Percent = (bin3 / binTotal) * 100;
cout << " Number of values in range 0.3-0.4: " << bin3 << endl;
cout << " Percentage of values in this interval: " << bin3Percent << "%" << endl;
cout << endl;
int bin4Percent = (bin4 / binTotal) * 100;
cout << " Number of values in range 0.4-0.5: " << bin4 << endl;
cout << " Percentage of values in this interval: " << bin4Percent << "%" << endl;
cout << endl;
int bin5Percent = (bin5 / binTotal) * 100;
cout << " Number of values in range 0.5-0.6: " << bin5 << endl;
cout << " Percentage of values in this interval: " << bin5Percent << "%" << endl;
cout << endl;
int bin6Percent = (bin6 / binTotal) * 100;
cout << " Number of values in range 0.6-0.7: " << bin6 << endl;
cout << " Percentage of values in this interval: " << bin6Percent << "%" << endl;
cout << endl;
int bin7Percent = (bin7 / binTotal) * 100;
cout << " Number of values in range 0.7-0.8: " << bin7 << endl;
cout << " Percentage of values in this interval: " << bin7Percent << "%" << endl;
cout << endl;
int bin8Percent = (bin8 / binTotal) * 100;
cout << " Number of values in range 0.8-0.9: " << bin8 << endl;
cout << " Percentage of values in this interval: " << bin8Percent << "%" << endl;
cout << endl;
int bin9Percent = (bin9 / binTotal) * 100;
cout << " Number of values in range 0.9-1.0: " << bin9 << endl;
cout << " Percentage of values in this interval: " << bin9Percent << "%" << endl;
cout << endl;
}
get_normal returns a long, which cannot be between 0 and 1, since it is an integer. Storing the integer returned by the function into a double (Z) does not magically restore the discarded fractional part.
I think you should use floating point arithmetic (that is, doubles) in get_normal, and also change the return type.
By the way, the C++ standard library has lots of random number distributions. You might want to use it instead of trying to write your own.
M is too big, in the limit of a long. So any long divided (or modulus) by this M will result in 0. Perphaps you should use unsigned long long.
Also:
Instead of R = sqrt(-2 * log(x1)); try R= sqrt(fabs(2 * log(x1)));
Also
phi = (2 * M_PI*x2);
u = R*cos(phi);
phi is always an multiple of 2*PI, so cos(phi)= 1.

Variance for Fibonacci numbers C++

Hello I wrote a c++ program to calculate Fibonacci numbers.
Basically I want my program to calculate let's say for example 10 Fibonacci numbers and then calculate their variance and standard deviation. At the moment I managed to get program to calculate Fibonacci numbers, but I don't know how I can load these numbers straight away to calculate variance and standard deviation. So I'm asking to input them and save them in array x, and then I calculate variance and standard deviation.
#include <conio.h>
#include <iostream>
#include <windows.h>
#include <math.h>
using namespace std;
int n,i,one=0,two=1,ne;
//one -> first number
//two -> second number
//ne -> next number
float x[100], sum=0, avg, vari=0, vari2, sd;
int main()
{
cout << "Enter how many Fibonacci numbers you want\n" << endl;
cin >> n;
cout << "\nFirst " << n << " Fibonacci numbers are : " << endl;
for ( i=0 ; i<n ; i++ )
{
if ( i<=1 )
ne=i;
else
{
ne=one+two;
one=two;
two=ne;
}
cout << ne << endl;
}
for (i=0; i<n; i++)
{
cout << "Input your Fibonacci numbers ";
cin >> x[i];
sum = sum + x[i];
}
avg = sum/n;
for (i=0; i<n; i++)
{
vari = vari + pow((x[i] - avg),2);
}
vari2 = vari/n;
sd = sqrt(vari2);
cout << "The sum of the numbers: " << sum << endl;
cout << "The average of the numbers: " << avg << endl;
cout << "The variance of the numbers: " << vari2 << endl;
cout << "The standard deviation of the numbers: " << sd << endl;
_getch();
}
This is new code:
Everything works well, apart from variance.
I don't know why variance is calculated incorrectly.
#include <conio.h> #include <iostream>
#include <windows.h>
#include <math.h>
using namespace std;
int n,i,one=0,two=1,ne;
//one -> first number
//two -> second number
//ne -> next number
float x[10000], sum=0, avg, vari=0, vari2, sd;
int main()
{
cout << "Enter how many Fibonacci numbers you want\n" << endl;
cin >> n;
cout << "\nFirst " << n << " Fibonacci numbers are : " << endl;
for ( i=0 ; i<n ; i++ )
{
if ( i<=1 )
ne=i;
else
{
ne=one+two;
one=two;
two=ne;
}
cout << ne << endl;
sum = sum + ne;
avg = sum/n;
}
for (i=0; i<n; i++)
{
vari = vari + pow((x[i] - avg),2);
}
vari2 = vari/n;
sd = sqrt(vari2);
cout << "The sum of the numbers: " << sum << endl;
cout << "The average of the numbers: " << avg << endl;
cout << "The variance of the numbers: " << vari2 << endl;
cout << "The standard deviation of the numbers: " << sd << endl;
_getch();
}
No need to create a for loop for sum and average, their code can be implemented inside the first loop itself:
for ( i=0 ; i<n ; i++ )
{
if ( i<=1 )
ne=i;
else
{
ne=one+two;
one=two;
two=ne;
}
cout << ne << endl;
sum = sum + ne;
avg = sum/n;
Now for variance and sd, you can create a function for each to calculate their values:
double funcvari(double d){
vari = vari + pow((ne - d),2);
vari2 = vari/n;
return vari2;
}
double funcsd(double fd){
sd = sqrt(fd);
return sd;
}
Live Demo