digitalmars.D.bugs - Very strange? Code generation bug?
- Ivan Senji (33/33) Apr 11 2006 with this program:
- Tom S (21/30) Apr 11 2006 This is what happens:
- BCS (7/52) Apr 11 2006 Well if you pull the rand out you get a different wrong range (~[-3,1])
- Dave (30/75) Apr 11 2006 Give this a shot:
- Ivan Senji (7/7) Apr 11 2006 Thank you guys for replying and especially Tom S for explaining this, I
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?
Apr 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 +/
Apr 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?
Apr 11 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"); }
Apr 11 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 - :)
Apr 11 2006