1

I came across a problem which really confused me.
I was trying to calculate the values of f(x,y) = (y^3)/(x^2+y^2) at some random points on -1 < x < 1 and -1 < y < 1.

Here is my code:

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

#define f(x, y) ( pow((y),3) / (pow((x),2) + pow((y),2)) )

double random(double min, double max)
{
    double m;
    m = rand()/(double)RAND_MAX;
    return (min + m * (max - min));
}

void main()
{
    int i; 
    double v;
    
    for(i = 0; i < 500; i++)
    {
        v = f(random(-1,1), random(-1,1));
        printf("%lf\n", s);
    }
}

And then i got some very weird values which are greater than 1 or smaller than -1 (which are the maximum and minimum f can get on -1<x<1 and -1<y<1).

On the other hand, when i changed my code by using 2 variables carrying random x and y and then plug them into f:

    double x, y;
    for(i = 0; i < 500; i++)
    {
        x = random(-1,1);
        y = random(-1,1);
        v = f(x, y);
        printf("%lf\n", s);
    }

the problem disappeard.
Can anyone please help me explain this? Thanks in advance!

lurker
  • 56,987
  • 9
  • 69
  • 103
Katie
  • 11
  • 1
  • 2
    In the first, the `y` expression has two different values. In the second, `y` is the same value. If you expand the macro, you will see. – Weather Vane Jan 01 '22 at 09:47
  • 2
    https://stackoverflow.com/questions/39439181/what-is-double-evaluation-and-why-should-it-be-avoided - avoid macros when a plain function is sufficient. – Mat Jan 01 '22 at 09:50
  • 1
    Rewrite `f()` as a function, and your problem will go away. – jxh Jan 01 '22 at 09:53
  • 1
    ...it expands to `( pow((random(-1,1)),3) / (pow((random(-1,1)),2) + pow((random(-1,1)),2)) )`. You have called `random` three times, but in the second example you call `random` twice. So they aren't the same. – Weather Vane Jan 01 '22 at 09:53

1 Answers1

2

In the first example:

f(random(-1, 1), random(-1, 1));

will be:

(pow((random(-1, 1)),3) / (pow((random(-1, 1)),2) + pow((random(-1, 1)),2)))

As you can see: random(-1, 1) in (pow((random(-1, 1)),3) will not equal to random(-1, 1) in pow((random(-1, 1)),2)), although you want it to be the same value.

But in the second example:

f(x, y);

will be:

( pow((y),3) / (pow((x),2) + pow((y),2)) )

which y in pow((y),3) is equal to y in pow((y),2), cause they have the same value

Don't use macro. Instead, use a function:

#define f(x, y) ( pow((y),3) / (pow((x),2) + pow((y),2)) )

to

double f(double x, double y)
{
    return pow((y),3) / (pow((x),2) + pow((y),2));
}