Thread overview
Very strange? Code generation bug?
Apr 11, 2006
Ivan Senji
Apr 11, 2006
Tom S
Apr 11, 2006
BCS
Apr 12, 2006
Dave
Apr 12, 2006
Ivan Senji
April 11, 2006
with this program:

<code>
import std.stdio;
import std.random;

float random1()
{
  float f = rand()%101;
  return (f-50)/50;
}

float random2()
{
  return (rand()%101-50)/50;
}

void main()
{
  for(int i=0;i<10;i++)
  {
    writef(random1(), " ");
  }

  writefln("\n");

  for(int i=0;i<10;i++)
  {
    writef(random2(), " ");
  }
}
</code>

i get output something like (Windows XP, DMD 0.153):

0.4 0.28 -0.46 0.2 0.48 0.7 -0.7 -0.18 -0.56 0.2

0 8.58993e+07 8.58993e+07 0 8.58993e+07 8.58993e+07 0 0 0 0


The problem is both functions random1 and random2 should be returning a number between -1 and 1 and they are doing the same calculation, but there is something wrong with random2.

Can someone please confirm this?
April 11, 2006
Ivan Senji wrote:
> float random1()
> {
>   float f = rand()%101;
>   return (f-50)/50;
> }

This is what happens:
1. rand() returns a random uint. It gets warped in the range 0 .. 100
2. the uint from 0 .. 100 is stored into a float
3. you subtract 50 and divide by 50. everything is fine.

> float random2()
> {
>   return (rand()%101-50)/50;
> }

This is what happens:
1. rand() returns a random uint. It gets warped in the range 0-100
2. you subtract 50 from the uint in range 0 .. 100, thus possibly wrapping it around its 0xffffffff boundary, thus getting an uint in range (0xffffffff - 50) .. 50
3. you divide the uint by 50, thus yielding a very big number if it were from the range (0xffffffff - 50) .. 0xffffffff or 1 if it were 50 or 0 if it were from the range 0 .. 49


Hope this helps :)


-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O !M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y
------END GEEK CODE BLOCK------

Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
April 11, 2006
Well if you pull the rand out you get a different wrong range (~[-3,1])

float random3()
{
	int r = rand();
	return cast(float)((r%101) - 50)/50.0;
}




Ivan Senji wrote:
> with this program:
> 
> <code>
> import std.stdio;
> import std.random;
> 
> float random1()
> {
>   float f = rand()%101;
>   return (f-50)/50;
> }
> 
> float random2()
> {
>   return (rand()%101-50)/50;
> }
> 
> void main()
> {
>   for(int i=0;i<10;i++)
>   {
>     writef(random1(), " ");
>   }
> 
>   writefln("\n");
> 
>   for(int i=0;i<10;i++)
>   {
>     writef(random2(), " ");
>   }
> }
> </code>
> 
> i get output something like (Windows XP, DMD 0.153):
> 
> 0.4 0.28 -0.46 0.2 0.48 0.7 -0.7 -0.18 -0.56 0.2
> 
> 0 8.58993e+07 8.58993e+07 0 8.58993e+07 8.58993e+07 0 0 0 0
> 
> 
> The problem is both functions random1 and random2 should be returning a
> number between -1 and 1 and they are doing the same calculation, but
> there is something wrong with random2.
> 
> Can someone please confirm this?
April 12, 2006
Ivan Senji wrote:
> with this program:
> 
> <code>
> import std.stdio;
> import std.random;
> 
> float random1()
> {
>   float f = rand()%101;
>   return (f-50)/50;
> }
> 
> float random2()
> {
>   return (rand()%101-50)/50;
> }
> 
> void main()
> {
>   for(int i=0;i<10;i++)
>   {
>     writef(random1(), " ");
>   }
> 
>   writefln("\n");
> 
>   for(int i=0;i<10;i++)
>   {
>     writef(random2(), " ");
>   }
> }
> </code>
> 
> i get output something like (Windows XP, DMD 0.153):
> 
> 0.4 0.28 -0.46 0.2 0.48 0.7 -0.7 -0.18 -0.56 0.2
> 
> 0 8.58993e+07 8.58993e+07 0 8.58993e+07 8.58993e+07 0 0 0 0
> 
> 
> The problem is both functions random1 and random2 should be returning a
> number between -1 and 1 and they are doing the same calculation, but
> there is something wrong with random2.
> 
> Can someone please confirm this?

Give this a shot:

;---

import std.stdio;
import std.random;

float random1()
{
  float f = rand()%101;
  return (f-50)/50;
}

float random2()
{
  //return (rand()%101-50)/50;
  return (cast(float)(rand()%101)-50)/50;
}

void main()
{
  rand_seed(10,10);
  for(int i=0;i<10;i++)
  {
    writef(random1(), " ");
  }

  writefln("\n");

  rand_seed(10,10);
  for(int i=0;i<10;i++)
  {
    writef(random2(), " ");
  }

  writefln("\n");
}
April 12, 2006
Thank you guys for replying and especially Tom S for explaining this, I get it now. It wasn't D it was me.

What works great is what Dave suggested
return (cast(float)(rand()%101)-50)/50;
but this shorter version works also
return (rand()%101)-50.)/50;

What I have learned is to be more careful with unsigned numbers and - :)