Home > Software design >  Some sort of issue with simple int/double operations
Some sort of issue with simple int/double operations

Time:01-21

I am new to C and I tried to put together a (only slightly) nontrivial piece of code, in which I use an array to store the values of atan(x) in bins of width dx from 0 to 1, then use the rectangular method to compute the integral of atan(x)dx from 0 to 1. The code should loop while successively making dx smaller to see the integral converge to the analytical result. I have been totally unable to figure out why I get expected outputs for most entries in the loop, but (some number)e 268 for the 7th/8th/15th outputs; I imagine it has something to do with int/double casting but the irregularity of it is very strange to me.

#include <stdio.h>
#include <math.h>

int main() {
    int array_len = 20;
    int array_len_new;
    int num_conv = 18;
    double linspace[200];
    double conv_array[200];
    double PI = 3.142857;
    double result;
    int i;
    int j;
            
    for (i = 0; i < num_conv; i  ) {
        array_len_new = array_len   10*i;
        double dx = 1./array_len_new;
        for (j = 0; j < array_len_new; j  ) {
            linspace[j] = j* 1.0/array_len_new;
            conv_array[i]  = atan(linspace[j])*dx;
        }
        printf("Result for %d bins is: %e\n", array_len_new, conv_array[i]);
    }

    printf("Converged result: %e\n", (PI-log(4.))/4.0);
    return 0;
}

Output:

Result for 20 bins is: 4.190854e-001
Result for 30 bins is: 4.256883e-001
Result for 40 bins is: 4.289811e-001
Result for 50 bins is: 4.309539e-001
Result for 60 bins is: 4.322680e-001
Result for 70 bins is: 4.332061e-001
Result for 80 bins is: 2.308177e 268
Result for 90 bins is: 2.308177e 268
Result for 100 bins is: 4.348934e-001
Result for 110 bins is: 4.352511e-001
Result for 120 bins is: 4.355492e-001
Result for 130 bins is: 4.358013e-001
Result for 140 bins is: 4.360175e-001
Result for 150 bins is: 4.362047e-001
Result for 160 bins is: 2.316093e 268
Result for 170 bins is: 4.365131e-001
Result for 180 bins is: 4.366416e-001
Result for 190 bins is: 4.367566e-001
Converged result: 4.391407e-001

EDIT: I have found that the issue resolves itself if I change the length of conv_array (which only needs 18 values, I made it big because I thought it wouldn't matter) from 200 to 18, or even 100. Why could this possibly be the case?

CodePudding user response:

You do not initialize the elements of conv_array. As a non-static local variable, its initial value is indeterminate. In particular, it is not safe to assume that it will be zero-initialized, but your code relies on exactly that assumption. Declaring it with an initializer should help:

    // ...
    double linspace[200];
    double conv_array[200] = {0};
    double PI = 3.14159265358979;
    // ...

The = {0} says that the first element is to be initialized to 0, and if any element is initialized then those without explicit initializers are implicitly default-initialized (to 0).

Personally, however, I would not use an array at all where you use conv_array, nor where you use linspace. Try this on for size:

#include <stdio.h>
#include <math.h>

int main() {
    int base_num_bins = 20;
    int num_cycles = 18;
    double PI = 3.14159265358979;
            
    for (int i = 0; i < num_cycles; i  ) {
        int num_bins = base_num_bins   10 * i;
        double dx = 1. / num_bins;
        double integral = 0;

        for (int j = 0; j < num_bins; j  ) {
            integral  = atan((double) j / num_bins) * dx;
        }
        printf("Result for %d bins is: %e\n", num_bins, integral);
    }

    printf("Converged result: %e\n", (PI - log(4.)) / 4.0);
    return 0;
}

CodePudding user response:

conv_array has not been initialised, but you do

conv_array[i]  = atan(linspace[j])*dx;

I suggest

double conv_array[200] = { 0 };

Side issue:

double PI = 3.142857;

might be ok with float but it isn't a very accurate value for π when working with double. I suggest using M_PI instead of double PI; and with MSVC you'll also need

#define _USE_MATH_DEFINES
  •  Tags:  
  • c
  • Related