This question already has an answer here:
Dividing two integers to produce a float result [duplicate]
(1 answer)
Closed 4 years ago.
This is my code and i'm trying to calculate this series : ((-1)^n)*n/(n+1) that n started from 1 to 5, code is not working correctly, anyone can help ?
int main(){
int i,n;
double sum1;
for (i=1; i<6; i++)
sum1 += (pow(-1,i))*((i)/(i+1));
cout<<sum1;
return 0;
}
The true answer at the end must be equal to -0.6166666666666667 which code cant calculate it correctly.
I calculated series from here. Is there any special function to do summation ?
Make sure to initialize your variables before you use them. You initialize i afterwards so it's fine like this, but sum1 needs to be initialized:
double sum1 = 0.0;
For the summation, even if the result is assigned to a double, the intermediate results might not be and integer devision result in truncated values. For this reason, double literals should be used (such as 2.0 instead of 2) and i should be casted where applicable:
sum1 += (pow(-1, i))*(((double)i) / ((double)i + 1.0));
Finally, to get the desired precision, std::setprecision can be used in the print. The final result could look like this:
int main() {
int i;
double sum1 = 0.0;
for (i = 1; i < 6; i++)
sum1 += (pow(-1, i))*(((double)i) / ((double)i + 1.0));
std::cout << std::setprecision(15) << sum1 << std::endl;
return 0;
}
Output:
-0.616666666666667
Always init variables before usage. double sum1 = 0;
((i) / (i + 1)) performs integer division, the result is 0 for any i.
Use for the pow function to find power of -1 is extremely irrational
int main() {
int i;
double sum1 = 0;
double sign = -1;
for (i = 1; i < 6; i++)
{
sum1 += sign * i / (i + 1);
sign *= -1.0;
}
std::cout << sum1;
return 0;
}
Try this instead
for (i = 0; i <= 5; i++) // from 0 to 5 inclusively
sum1 += (pow(-1, i)) * (static_cast<double>(i) / (i + 1));
Related
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;
}
I am trying to compute the Anderson-Darling test found here. I followed the steps on Wikipedia and made sure that when I calculate the average and standard deviation of the data I am testing denoted X by using MATLAB. Also, I used a function called phi for computing the standard normal CDF, I have also tested this function to make sure it is correct which it is. Now I seem to have a problem when I actually compute the A-squared (denoted in Wikipedia, I denote it as A in C++).
Here is my function I made for Anderson-Darling Test:
void Anderson_Darling(int n, double X[]){
sort(X,X + n);
// Find the mean of X
double X_avg = 0.0;
double sum = 0.0;
for(int i = 0; i < n; i++){
sum += X[i];
}
X_avg = ((double)sum)/n;
// Find the variance of X
double X_sig = 0.0;
for(int i = 0; i < n; i++){
X_sig += (X[i] - X_avg)*(X[i] - X_avg);
}
X_sig /= n;
// The values X_i are standardized to create new values Y_i
double Y[n];
for(int i = 0; i < n; i++){
Y[i] = (X[i] - X_avg)/(sqrt(X_sig));
//cout << Y[i] << endl;
}
// With a standard normal CDF, we calculate the Anderson_Darling Statistic
double A = 0.0;
for(int i = 0; i < n; i++){
A += -n - 1/n *(2*(i) - 1)*(log(phi(Y[i])) + log(1 - phi(Y[n+1 - i])));
}
cout << A << endl;
}
Note, I know that the formula for Anderson-Darling (A-squared) starts with i = 1 to i = n, although when I changed the index to make it work in C++, I still get the same result without changing the index.
The value I get in C++ is:
-4e+006
The value I should get, received in MATLAB is:
0.2330
Any suggestions are greatly appreciated.
Here is my whole code:
#include <iostream>
#include <math.h>
#include <cmath>
#include <random>
#include <algorithm>
#include <chrono>
using namespace std;
double *Box_Muller(int n, double u[]);
double *Beasley_Springer_Moro(int n, double u[]);
void Anderson_Darling(int n, double X[]);
double phi(double x);
int main(){
int n = 2000;
double Mersenne[n];
random_device rd;
mt19937 e2(1);
uniform_real_distribution<double> dist(0, 1);
for(int i = 0; i < n; i++){
Mersenne[i] = dist(e2);
}
// Print Anderson Statistic for Mersenne 6a
double *result = new double[n];
result = Box_Muller(n,Mersenne);
Anderson_Darling(n,result);
return 0;
}
double *Box_Muller(int n, double u[]){
double *X = new double[n];
double Y[n];
double R_2[n];
double theta[n];
for(int i = 0; i < n; i++){
R_2[i] = -2.0*log(u[i]);
theta[i] = 2.0*M_PI*u[i+1];
}
for(int i = 0; i < n; i++){
X[i] = sqrt(-2.0*log(u[i]))*cos(2.0*M_PI*u[i+1]);
Y[i] = sqrt(-2.0*log(u[i]))*sin(2.0*M_PI*u[i+1]);
}
return X;
}
double *Beasley_Springer_Moro(int n, double u[]){
double y[n];
double r[n+1];
double *x = new double(n);
// Constants needed for algo
double a_0 = 2.50662823884; double b_0 = -8.47351093090;
double a_1 = -18.61500062529; double b_1 = 23.08336743743;
double a_2 = 41.39119773534; double b_2 = -21.06224101826;
double a_3 = -25.44106049637; double b_3 = 3.13082909833;
double c_0 = 0.3374754822726147; double c_5 = 0.0003951896511919;
double c_1 = 0.9761690190917186; double c_6 = 0.0000321767881768;
double c_2 = 0.1607979714918209; double c_7 = 0.0000002888167364;
double c_3 = 0.0276438810333863; double c_8 = 0.0000003960315187;
double c_4 = 0.0038405729373609;
// Set r and x to empty for now
for(int i = 0; i <= n; i++){
r[i] = 0.0;
x[i] = 0.0;
}
for(int i = 1; i <= n; i++){
y[i] = u[i] - 0.5;
if(fabs(y[i]) < 0.42){
r[i] = pow(y[i],2.0);
x[i] = y[i]*(((a_3*r[i] + a_2)*r[i] + a_1)*r[i] + a_0)/((((b_3*r[i] + b_2)*r[i] + b_1)*r[i] + b_0)*r[i] + 1);
}else{
r[i] = u[i];
if(y[i] > 0.0){
r[i] = 1.0 - u[i];
r[i] = log(-log(r[i]));
x[i] = c_0 + r[i]*(c_1 + r[i]*(c_2 + r[i]*(c_3 + r[i]*(c_4 + r[i]*(c_5 + r[i]*(c_6 + r[i]*(c_7 + r[i]*c_8)))))));
}
if(y[i] < 0){
x[i] = -x[i];
}
}
}
return x;
}
double phi(double x){
return 0.5 * erfc(-x * M_SQRT1_2);
}
void Anderson_Darling(int n, double X[]){
sort(X,X + n);
// Find the mean of X
double X_avg = 0.0;
double sum = 0.0;
for(int i = 0; i < n; i++){
sum += X[i];
}
X_avg = ((double)sum)/n;
// Find the variance of X
double X_sig = 0.0;
for(int i = 0; i < n; i++){
X_sig += (X[i] - X_avg)*(X[i] - X_avg);
}
X_sig /= (n-1);
// The values X_i are standardized to create new values Y_i
double Y[n];
for(int i = 0; i < n; i++){
Y[i] = (X[i] - X_avg)/(sqrt(X_sig));
//cout << Y[i] << endl;
}
// With a standard normal CDF, we calculate the Anderson_Darling Statistic
double A = -n;
for(int i = 0; i < n; i++){
A += -1.0/(double)n *(2*(i+1) - 1)*(log(phi(Y[i])) + log(1 - phi(Y[n - i])));
}
cout << A << endl;
}
Let me guess, your n was 2000. Right?
The major issue here is when you do 1/n in the last expression. 1 is an int and ao is n. When you divide 1 by n it performs integer division. Now 1 divided by any number > 1 is 0 under integer division (think if it as only keeping only integer part of the quotient. What you need to do is cast n as double by writing 1/(double)n.
Rest all should work fine.
Summary from discussions -
Indexes to Y[] should be i and n-1-i respectively.
n should not be added in the loop but only once.
Minor fixes like changing divisor to n instead of n-1 while calculating Variance.
You have integer division here:
A += -n - 1/n *(2*(i) - 1)*(log(phi(Y[i])) + log(1 - phi(Y[n+1 - i])));
^^^
1/n is zero when n > 1 - you need to change this to, e.g.: 1.0/n:
A += -n - 1.0/n *(2*(i) - 1)*(log(phi(Y[i])) + log(1 - phi(Y[n+1 - i])));
^^^^^
VS minimum double value = 2.2250738585072014e-308. atof function converts string to double value such as when you look at this value in the debugger you get original string representation.
double d = atof("2.2250738585072014e-308"); // debugger will show 2.2250738585072014e-308
As we can see, double value is not denormalized (there is no DEN)
I try to achieve the same precision when converting string to double. Here is the code:
double my_atof(char* digits, int digits_length, int ep)
{
int idot = digits_length;
for (int i = 0; i < digits_length; i++)
{
if (digits[i] == '.')
{
idot = i;
break;
}
}
double accum = 0.0;
int power = ep + idot - 1;
for (int i = 0; i < digits_length; i++)
{
if (digits[i] != '.')
{
if (digits[i] != '0')
{
double base_in_power = 1.0;
if (power >= 0)
{
for (int k = 0; k < power; k++) base_in_power *= 10.0;
}
else if (power < 0)
{
for (int k = 0; k < -power; k++) base_in_power *= 0.1;
}
accum += (digits[i] - '0') * base_in_power;
}
power--;
}
else power = ep - 1;
}
return accum;
}
Now, let's try:
char* float_str = "2.2250738585072014";
int float_length = strlen(float_str);
double d = my_atof(float_str, float_length, -308);
Debugger shows that d = 2.2250738585072379e-308. I tried to substitute
for (int k = 0; k < -power; k++) base_in_power *= 0.1;
with
for (int k = 0; k < -power; k++) base_in_power /= 10.0;
but it results in denormalized value. How to achieve the same precision as VS does, such that debugger will show the same number?
The problem is with double representation of the 0.1 constant, or the division by 10.0, which produces exactly the same result: negative powers of ten have no exact representation in floating-point numbers, because they have no exact representation as a sum of negative powers of 2.
When you compute negative powers of ten by repeated multiplication, you accumulate the error. First few negative powers come out right, but after about 0.000001 the difference becomes visible. Run this program to see what is happening:
double p10[] = {
0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001, 0.000000001, 0.0000000001
};
int main(void) {
double a = 1;
for (int i = 0 ; i != 10 ; i++) {
double aa = a * 0.1;
double d = aa - p10[i];
printf("%d %.30lf\n", aa == p10[i], d);
a = aa;
}
return 0;
}
The output looks like this:
1 0.000000000000000000000000000000
1 0.000000000000000000000000000000
1 0.000000000000000000000000000000
1 0.000000000000000000000000000000
1 0.000000000000000000000000000000
0 0.000000000000000000000211758237
0 0.000000000000000000000026469780
0 0.000000000000000000000001654361
0 0.000000000000000000000000206795
0 0.000000000000000000000000025849
Demo.
The first few powers match exactly, but then some differences start appearing. When you use powers that you compute to compose the number during your string-to-float conversion, the accumulated errors make it into the final result. If the library function uses a look-up table (see this implementation for an example), the result that you get would be different from result that they get.
You can fix your implementation by hard-coding a table of negative powers of ten, and referencing this table instead of computing the powers manually. Alternatively you could construct a positive power of ten by consecutive multiplications, and then do a single division 1 / pow10 to construct the corresponding negative power (demo).
I've been trying to get this solved but without luck.
All I want to do is to differentiate a polynomial like P(x) = 3x^3 + 2x^2 + 4x + 5
At the end of the code, the program should evaluate this function and gives me just the answer.
The derivative of P(x) is P'(x) = 3*3x^2 + 2*2x + 4*1. If x = 1, the answer is 17.
I just don't get that answer no matter how I alter my loop.
/*
x: value of x in the polynomial
c: array of coefficients
n: number of coefficients
*/
double derivePolynomial(double x, double c[], int n) {
double result = 0;
double p = 1;
int counter = 1;
for(int i=n-1; i>=0; i--) //backward loop
{
result = result + c[i]*p*counter;
counter++; // number of power
p = p*x;
}
return result;
}
//Output in main() looks like this
double x=1.5;
double coeffs[4]={3,2.2,-1,0.5};
int numCoeffs=4;
cout << " = " << derivePolynomial(x,coeffs,numCoeffs) << endl;
The derivative of x ^ n is n * x ^ (n - 1), but you are calculating something completely different.
double der(double x, double c[], int n)
{
double d = 0;
for (int i = 0; i < n; i++)
d += pow(x, i) * c[i];
return d;
}
This would work, assuming that your polinomial is in the form c0 + c1x + c2x ^ 2 + ...
Demonstration, with another function that does the derivation as well.
Edit: alternative solution avoiding the use of the pow() function, with simple summation and repeated multiplication:
double der2(double x, double c[], int n)
{
double d = 0;
for (int i = 0; i < n - 1; i++) {
d *= x;
d += (n - i - 1) * c[i];
}
return d;
}
This works too. Note that the functions that take the iterative approach (those which don't use pow()) expect their arguments (the coefficients) in reverse order.
You need to reverse the direction of the loop. Start at 0 and go to n.
At the moment when you compute the partial sum for the n-th power p is 1. For the last one x^0 you your p will contain x^n-1 th power.
double derivePolynomial(double x, double c[], int n) {
double result = 0;
double p = 1;
int counter = 1;
for(int i=1; i<n; i++) //start with 1 because the first element is constant.
{
result = result + c[i]*p*counter;
counter++; // number of power
p = p*x;
}
return result;
}
double x=1;
double coeffs[4]={5,4,2,3};
int numCoeffs=4;
cout << " = " << derivePolynomial(x,coeffs,numCoeffs) << endl;
I can't figure out why I keep getting the result 1.#INF from my_exp() when I give it 1 as input. Here is the code:
double factorial(const int k)
{
int prod = 1;
for(int i=1; i<=k; i++)
prod = i * prod;
return prod;
}
double power(const double base, const int exponent)
{
double result = 1;
for(int i=1; i<=exponent; i++)
result = result * base;
return result;
}
double my_exp(double x)
{
double sum = 1 + x;
for(int k=2; k<50; k++)
sum = sum + power(x,k) / factorial(k);
return sum;
}
You have an integer overflow in your factorial function. This causes it to output zero. 49! is divisible by 2^32, so your factorial function will return zero.
Then you divide by it causing it to go infinity. So the solution is to change prod to double:
double prod = 1;
Instead of completely evaluating the power and the factorial terms for each term in your expansion, you should consider how the k'th term is related to the k-1'th term and just update each term based on this relationship. That will avoid the nasty overflows in your power and factorial functions (which you will no longer need). E.g.
double my_exp(double x)
{
double sum = 1.0 + x;
double term = x; // term for k = 1 is just x
for (int k = 2; k < 50; k++)
{
term = term * x / (double)k; // term[k] = term[k-1] * x / k
sum = sum + term;
}
return sum;
}
you should just reduce max of k form 50 to like 30 it will work;
and one question your code work just near 0 ?