Gameboy Development Forum

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.

Ads

#1 2015-08-13 02:19:02

ek82
Member
Registered: 2015-08-12
Posts: 10

Random number problem

Hello all. rand() does not seem to be working as I'm used to.

Code:

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:

Code:

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

 

#2 2015-08-13 02:33:34

Tauwasser
Member
Registered: 2010-10-23
Posts: 160

Re: Random number problem

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

 

#3 2015-08-13 11:02:08

Scazon
Member
From: Boston, MA
Registered: 2015-06-14
Posts: 24
Website

Re: Random number problem

Actually, try:

printf("%d\n", (UWORD)num);

printf expects 16-bit parameters, so what youre seeing printed is your number plus the next 8 random bits in memory.

Offline

 

#4 2015-08-13 22:42:14

ek82
Member
Registered: 2015-08-12
Posts: 10

Re: Random number problem

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

 

#5 2015-08-13 23:41:57

Scazon
Member
From: Boston, MA
Registered: 2015-06-14
Posts: 24
Website

Re: Random number problem

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

 

#6 2015-08-15 02:30:08

ek82
Member
Registered: 2015-08-12
Posts: 10

Re: Random number problem

Thanks, so I tried:

Code:

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

 

#7 2017-03-29 15:28:36

AntonioND
Member
Registered: 2014-06-17
Posts: 134
Website

Re: Random number problem

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

 

#8 2017-03-29 21:31:44

MrElephant
Member
Registered: 2014-01-29
Posts: 40

Re: Random number problem

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.


Working in Gameboy BASIC.

Offline

 

#9 2017-03-30 17:55:14

AntonioND
Member
Registered: 2014-06-17
Posts: 134
Website

Re: Random number problem

UINT8 r = ((UINT8)rand()) % (UINT8)4;

That SHOULD work. But well, GBDK is broken in a lot of ways, so maybe not.

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson