views:

184

answers:

4

I want to generate random numbers from -n to n excluding 0. Can someone provide me the code in C? How to exclude 0?

+1  A: 

Take a look here: http://www.phanderson.com/C/random.html

Konamiman
+3  A: 

The simplest thing I can suggest to do is to generate a Random number between 0 and 2n and then to do the math trick:

result= n - randomNumber

Although 0 might be very unlikely you can check for that using an If and redo the random number generation.

Chris
+9  A: 

One idea might be to generate a random number x in the range [1,2n], inclusive. Then return -(x - n) for x larger than n, else just return x.

This should work:

int my_random(int n)
{
  const int x = 1 + rand() / (RAND_MAX / (2 * n) + 1);

  return x > n ? -(x - n) : x;
}

See the comp.lang.c FAQ for more information about how to use rand() safely; it explains the above usage.

unwind
Thanks. Chris just posted the answer before u so I did that.
avd
+1  A: 
int random(int N) 
{ 
  int x;
  do{
    x=rand()%(N*2+1)-N;
  }while(x==0);
  return x;
}

It chooses a number from -N to N, but keeps on doing it if it is 0.

An alternative, as suggested in the comments, generates a number between -N and N-1 and increments it if its positive or 0:

int random(int N) 
{ 
  int x;      
  x=rand()%(N*2)-N;
  if(x>=0) x++;
  return x;
}
iWerner
A do-while dependent on a random value could execute for a long, long time! But you could get rid of the non-deterministic execution time by reducing the range of the random result by 1, then artificially converting any 0 result to the missing boundary result. No loop needed.
Casey Barker
I don't agree with your statement that it would take a "long, long time": The odds of x being 0 (and therefore, the loop repeating) is 1/(2N+1), which is quite small for large values of N.Nevertheless, I've incorporated your suggestion into my answer, which I think yields a better solution for this particular problem, so thanks :)
iWerner
Ah... I didn't say it "would" take a long time, but rather that it "could" take a long time. There is a difference! :)I apologize if that sounds cheeky. I work in real-time software, where anything that can't be absolutely guaranteed to finish in some deterministic time "could take a long time." Technically speaking, your first version is O(?) and your second version is O(1) (or at worst, no more complex than "rand"). So in terms of determinism, your second version is a great improvement.Nicely done, btw. My "convert the 0 to the boundary" suggestion wouldn't have been as pretty.
Casey Barker