0

What I'm trying to do is generating some random numbers (-1<x<1) and then saving them in the array. p[i] = (double)2*rand()/RAND_MAX-1;

So far there's no error (random numbers were reasonably generated), but problem occurred when I tried to get values from the array. q += p[i]*p[j]

The array p[j] gives strange values like 0 (yes there can be zero, but it looks strange that array gives 0 continuously) or very big value like 28040310013302517619982145582267442588916597218393832117220025500645045329090733358176461602261387426622486260295380601312859137588835453228348262580224.000000. Not always, but sometimes.

I think there should be no error. I've checked that both indices i and j are inside the array range. Did I make any mistakes? I've attached my code below. (My code is calculating a totally meaningless thing, so you don't have to care about that.)

Thanks!

#include <stdio.h>
#include <stdlib.h>

int main(){

        FILE *file;
        file = fopen("result.txt","w");
        int N = 10000;
        double p[N]={0};

        for(int i=0;i<N;i++){
                p[i] = (double)2*rand()/RAND_MAX-1; //range[-1, 1]
        }
        int j;
        double x,y;
        for(int n=-100; n<=100; n++){
                double q = 0;
                for(int i=0; i<N; i++){
                        j = (i+n)%N;
                        q += p[i]*p[j];
                }
                fprintf(file,"%d\t%f\n",n,q);
        }
        fclose(file);

}

  • 2
    OT: Instead of the cast in `(double)2`, why not use a `double` value to begin with, as in `2.0`? – Some programmer dude Nov 06 '22 at 13:29
  • As for debugging your problem, start with a much smaller collection of values (instead of `10000`, perhaps only `100`?). And don't use random values, use well-known values (going from `0` to `RAND_MAX`). Then print all the values used to compute `j` and `q`, and print all the values of `j` and the result of `p[i] * p[j]`, as well as `p[i]` and `p[j]`, to see when and where values start to get wrong. – Some programmer dude Nov 06 '22 at 13:32
  • 2
    your code has undefined behavior by accessing out-of-bound, just enable [Asan](https://en.wikipedia.org/wiki/AddressSanitizer) and you'll see: https://godbolt.org/z/9bKW73q8s Note that `double p[N]={0};` is invalid in C++, it's only an extension in GCC. I had to change it to `#define` to make it work. You should use `constexpr` instead – phuclv Nov 06 '22 at 13:34
  • 1
    @phuclv The question *is* tagged C, and there's no mention of C++ in it. :) – Some programmer dude Nov 06 '22 at 13:36
  • 2
    As a hint, what is the result of `(i+n)%N` when `n` is negative? – Some programmer dude Nov 06 '22 at 13:37
  • @Someprogrammerdude yes that's because I used Godbolt. Didn't notice the tag – phuclv Nov 06 '22 at 13:39
  • 1
    Does this answer your question? [Modulo operation with negative numbers](https://stackoverflow.com/questions/11720656/modulo-operation-with-negative-numbers) – phuclv Nov 06 '22 at 13:41

1 Answers1

1
  1. p[N]={0}; is invalid in C. Variable size arrays cannot be initialized

You can easily debug the issue:

int main(){
        int N = 100;
        double p[N];

        for(int i=0;i<N;i++)
            p[i] = (2.0*rand())/RAND_MAX-1; //range[-1, 1]

        int j;
        double x,y;
        for(int n=-100; n<=100; n++){
                double q = 0;
                for(int i=0; i<N; i++){
                    j = (i+n)%N;
                    if(i < 0 || i >= N || j < 0 || j >= N) 
                    {
                        printf("i = %d, j = %d ERROR\n", i, j);
                    }
                    q += p[i]*p[j];
                }
        printf("n=%d\tq=%f\n",n,q);
        }
}

When you run it you will notice that j is always negative. I do not know what you want to calculate but probably you want an absolute value of this index

int main()
{
    int N = 100;
    double p[N];

    for(int i=0;i<N;i++)
        p[i] = (2.0*rand())/RAND_MAX-1; //range[-1, 1]

    int j;
    double x,y;
    for(int n=-100; n<=100; n++){
            double q = 0;
            for(int i=0; i<N; i++){
                j = abs((i+n)%N);
                if(i < 0 || i >= N || j < 0 || j >= N) 
                {
                    printf("i = %d, j = %d ERROR\n", i, j);
                }
                q += p[i]*p[j];
            }
    printf("n=%d\tq=%f\n",n,q);
    }
}

https://godbolt.org/z/7dqM49b8a

0___________
  • 60,014
  • 4
  • 34
  • 74