Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
Hello all. rand() does not seem to be working as I'm used to.
INT8 num; num = rand() % 4; printf("%d\n", num);
I'm expecting a number between 0 and 3, inclusive, but instead I'm seeing numbers printed like: -19712
I looked inside the GBDK rand.h header file and see this prototype:
INT8 rand(void);
Am I doing something wrong? :s
EDIT:
This is interesting. So looks like rand() can return a negative number. The following seems to fix the issue:
int num; num = rand(); if(num < 0) num = num * -1; num = num % 4; printf("%d\n", num);
Perhaps this is just a GBDK quirk? I've never seen rand() return a negative.
Last edited by ek82 (2015-08-13 02:30:41)
Offline
Check out this StackOverflow answer.
Your first piece of code probably exposed a bug somewhere. The % operator automatically promotes the expression to int, which shouldn't be a problem as it should be implicitly converted. You should check out the produced assembler code to know for sure where the bug lies.
cYa,
Tauwasser
Offline
Ah, thanks for the tips. You were right in that casting to UWORD reduced the number of bits on display. Using a INT8 still seems to cause a little trouble in that most values stay in range but some times they don't. The workaround from my post earlier seems to help with that, though.
Last edited by ek82 (2015-08-13 22:50:16)
Offline
I think the other issue might be that rand() actually returns a UBYTE (UINT8) and you're storing it as a INT8. Rand() returns a number from 0-255, so having it as a signed integer might get it out of range.
Try changing INT8 to UINT8 or UBYTE. (But also, still always cast to UWORD when printing).
Offline
Thanks, so I tried:
UBYTE num; while(1){ num = rand() % 4; printf("%d\n", (UWORD)num); delay(500); }
Also tried using UINT8 for the num data type.
It almost works. The output I get is as follows:
0
254
0
1
3
2
3
255
.....
I'm curious what your output will be if you try that. Seems like the only way to keep it in range is by using a larger signed data type like INT16 and flipping the sign if it goes negative.
So using a larger signed I get something like:
0
-1
2
-3
1
....
They are always plus or minus the range by the mod %.
Last edited by ek82 (2015-08-16 03:09:08)
Offline
Try "num = ((UINT8)rand()) % 4;".
If you apply the modulo operator to a negative number, the result is negative, even if it is then casted to unsigned. Maybe it is extending the sign when expanding to 16 bits.
Last edited by AntonioND (2017-03-29 15:29:30)
Offline
Antonio, your method worked, but it is still going past the given range for example you give a range through 10, and it produces 250.
Offline