-1

I'm writing my own method to generate a random number with C as follows:

int randomNumber(){  
    int catch = *pCOUNTER;  
    int temp = catch;  
    temp /= 10;  
    temp *= 10;  
    return (catch - temp);  
}

pCounter is basically a pointer to a register in the device I'm using. The number in that register is always increasing so my idea is to take the first digit only.

At some point, the number returned becomes larger than 9 and I'm not sure if the problem is in my code or the device itself. The device is an Altera DE1 board.

Can anyone please help with that?

Thanks!

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
Sadiq
  • 2,249
  • 2
  • 24
  • 32
  • I hope this is a homework assignment. – Amir Afghani Apr 07 '11 at 23:29
  • 2
    You need to be careful of the signs of your integers. If `*pCOUNTER` is negative, then your method and all the other suggestions so far produce the wrong answer. If you cast a negative integer to an unsigned type, it will appear to be large. – rlibby Apr 07 '11 at 23:38
  • Note that if `*pCOUNTER` is unsigned, this can return negative values when `*pCOUNTER >= 2^32`. – user470379 Apr 07 '11 at 23:41

6 Answers6

4

Did you declare pCounter as volatile?

volatile unsigned *pCounter = (unsigned *)0xBADDECAF;

int randomNumber(){
    return *pCounter % 10;
}
pmg
  • 106,608
  • 13
  • 126
  • 198
  • Note that even if it _is_ marked volatile, many compilers are notorious for not always handling volatile variables properly: see http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf for an interesting read. – user470379 Apr 07 '11 at 23:46
1

Are you sure you're not looking to use %= instead of /= & *=?

octal9
  • 368
  • 1
  • 10
  • My logic is: if the catch is 1234 then temp /= 10 is 123 and temp *= 10 is 1230 so (catch - temp) = 1234 - 1230 = 4. – Sadiq Apr 07 '11 at 23:32
  • 1
    @Tomalak: `2 - 0` is still `2`. – pmg Apr 07 '11 at 23:35
  • @Uqi %= makes it less ambiguous. Other issues arise if *pCounter points to an unsigned. Have you tested what happens to this function when things start overflowing? – octal9 Apr 07 '11 at 23:45
1

To achieve what you're trying to do in your code:

int catch = *pCOUNTER;
return (catch % 10); // Returns only the ones digit

However, I question if this approach is anywhere close to being reasonably random...

Kromey
  • 1,202
  • 1
  • 10
  • 13
1

I suspect that your problem might be an 'optimization' introduced by the compiler - if you don't have pCOUNTER declared with the correct volatility, the compiler could be reading through the pointer more than once. I have no idea how many registers your processor might have - if there's not enough to hold catch in a register, it might read it multiple times (once to get something to do the temp calculations on, and again for the final return value).

Try the following, which should ensure that the pCOUNTER device/register is read exactly once:

int randomNumber(){  
    int catch = *(int volatile*)pCOUNTER;  
    int temp = catch;  
    temp /= 10;  
    temp *= 10;  
    return (catch - temp);  
}
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
0

If you're looking for a random digit (0-9 only), try this modification of your method.

int randomNumber(){  
    return ((*pCOUNTER) % 10);  
}

This isn't very random, though. If it's always increasing, presumably at a known rate then it's 100% predictable, not random at all.

Is the rand() function not allowed on that Altera board?

Edit:

You could always write your own PRNG. I did a Google search for "simple random number generator code", and found several simple examples. The simplest ones are along these lines:

int randomNumber()
{
    static long a = SomeSeedValue;

    a = (a * SomeNumber + AnotherNumber) % SomeLargePrimeNumber;
    return a % 65536;
}
David Yaw
  • 27,383
  • 4
  • 60
  • 93
-1

If you want to arbitrarily limit the result to 9:

return (catch - temp)%10;

I recommend using a macro constant to abstract the '10' though, otherwise it's a magic number.

Chris Browne
  • 1,582
  • 3
  • 15
  • 33