views:

89

answers:

3

I have written a source code to print random numbers within a specified limit.But it is also returning some negative numbers,is this normal?If not how do I rectify it?

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

int main( int argc, char* argv[])

{        

    int fd, n;
    fd = open("/dev/urandom", O_RDONLY);
    if(fd == -1)
    printf("ERROR: Cannot Open %s\n",argv[1]);

    read(fd, &n, sizeof(n));                      //n=random number
    printf("%d\n",1+n%6);                         //limiting n 

    /* 1+n%6 should give me random numbers only between
       1-6(correct me if I'm wrong),
       but somehow it even gives negative numbers*/        

    close(fd);

}
+2  A: 

In case the random number you read is negative (which is certainly possible), the modulus of it can also be negative. You should use an unsigned integer in order to make sure the result is in the range you want.

More information can be found here.

abyx
Note that using `abs()` may skew it. Use an unsigned integer instead.
Ignacio Vazquez-Abrams
@Ignacio - you are correct, of course. Edited, thanks!
abyx
+1  A: 

1 + n % 6 does not magically constrain the result to between 0-6. Run this to see.

#include <stdio.h>

int main(int argc, char* argv[]) {
  printf("%d\n", 1 + (-23) % 6);

  return 0;
}
Hitesh
+1  A: 

Wow, even I thought that the modulo operator when applied like

c=a%b

restricts c between integers [0,b-1].

However as K&R writes (pg 39, 2nd ed):

The expression x % yproduces the remainder when x is divided by y, and thus is zero when y divides x exactly.

So in effect what happens is:

c = sign(a) * ( abs(a)%abs(b) )

(where sign(a)=-1 for a<0 and +1 for a>=0)

It would be great if somebody could point out an actual reference to this behaviour in a book or C standard. This is what I figured out after experimentation with GCC v4.4.1.

Thanks for the great question. You kind of cleared my understanding of C modulus operator.

BiGYaN
Sadly, this broken behavior is required by C99 and allowed (as optional brain damage) by earlier versions of the C standard. If you're performing modulo by a power of 2, the way to get around this is simply use bitwise and instead of the `%` operator. Otherwise you're stuck writing ugly, slow code to compensate...
R..