Math.Random() always returns 0

classic Classic list List threaded Threaded
29 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Math.Random() always returns 0

Beric Holt
I've just finished upgrading my TileEngine game platform to use Lua
v5.1.

Everything is working fine, in fact I've even added better error
handling while loading scripts instead of using the old lua_dofile
syntax.  The only problem is that math.random() always returns zero,
even when called with parameters eg:
iResult = math.random(750,2000)

I use the random functionality for my Actor AI, so when it returns zero
all of the actors just stand there mutely.

I have randomised the seed with "math.randomseed( os.time())".  

Does anyone have any suggestions on why this might be happening?

Thanks
Beric Holt
Soap Dragon
http://buzzrick.emedia.net.nz 

Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

Lisa Parratt
Beric Holt wrote:
> Does anyone have any suggestions on why this might be happening?
>  
Have you configured Lua to use integer math? I seem to remember there
was a flaw in Lua 5 that stopped random numbers from working properly
with integer types, and I've not checked to see if it was fixed in 5.1.

--
Lisa
Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

David Jones-2
In reply to this post by Beric Holt

On May 24, 2006, at 11:02, Beric Holt wrote:

> I've just finished upgrading my TileEngine game platform to use Lua
> v5.1.
>
> Everything is working fine, in fact I've even added better error
> handling while loading scripts instead of using the old lua_dofile
> syntax.  The only problem is that math.random() always returns zero,
> even when called with parameters eg:
> iResult = math.random(750,2000)
>
> I use the random functionality for my Actor AI, so when it returns zero
> all of the actors just stand there mutely.
>
> I have randomised the seed with "math.randomseed( os.time())".
>
> Does anyone have any suggestions on why this might be happening?

Check that rand() is implemented properly on your platform.  
math.random calls rand from the standard C library.

People that care about using random numbers usually replace math.rand,
I recommend a combined tausworthe generator.


drj

Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

Daniel Collins
In reply to this post by Beric Holt
> Beric Holt wrote:
> > Does anyone have any suggestions on why this might be happening?

math.random relies on the C standard library function rand(). So I would
check that rand() works as expected.

> Have you configured Lua to use integer math? I seem to remember there
> was a flaw in Lua 5 that stopped random numbers from working properly
> with integer types, and I've not checked to see if it was
> fixed in 5.1.

That's interesting. I am currently using lua with lua_number set to int.
But as part of porting to my system I had to write my own replacements
for the math.random set of functions, and so I never noticed this
problem.

If you need a replacement for rand(), check out the mersenne twister
implementation that Luiz has on his website:
http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/


- DC

Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

Luiz Henrique de Figueiredo
In reply to this post by Lisa Parratt
> Have you configured Lua to use integer math? I seem to remember there
> was a flaw in Lua 5 that stopped random numbers from working properly
> with integer types, and I've not checked to see if it was fixed in 5.1.

Almost the whole math library does not make sense if lua_Number is int.
The only exceptions are abs, max, min, random (with args), randomseed.
For integer math, other functions such as idiv (quotient+remainder),
gcd, ipow, and support for modular arithmetic are probably what is needed.
I think they should go into a separate library.
--lhf
Reply | Threaded
Open this post in threaded view
|

RE: Math.Random() always returns 0

Incley, Mark
In reply to this post by Beric Holt
Beric,

I experienced the exact same thing when I upgraded InkSpector
(Windows/DirectX) from Lua 5.0 to 5.1. By using the
D3DCREATE_FPU_PRESERVE option when creating the D3D device, the
math.random problem vanished.

View this message for more info
http://lua-users.org/lists/lua-l/2006-01/msg00348.html

Cheers,
Mark.

-----Original Message-----
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Beric Holt
Sent: 24 May 2006 11:03
To: Lua list
Subject: Math.Random() always returns 0

I've just finished upgrading my TileEngine game platform to use Lua
v5.1.

Everything is working fine, in fact I've even added better error
handling while loading scripts instead of using the old lua_dofile
syntax.  The only problem is that math.random() always returns zero,
even when called with parameters eg:
iResult = math.random(750,2000)

I use the random functionality for my Actor AI, so when it returns zero
all of the actors just stand there mutely.

I have randomised the seed with "math.randomseed( os.time())".  

Does anyone have any suggestions on why this might be happening?

Thanks
Beric Holt
Soap Dragon
http://buzzrick.emedia.net.nz 

Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

Luiz Henrique de Figueiredo
In reply to this post by Luiz Henrique de Figueiredo
BTW, there's always a simple replacement for rand() suggested by Knuth,
as quoted in Numerical Recipes:

do
        local x=0
        local a=1664525
        local c=1013904223
        function randomseed(s)
                x=s
        end
        function rand()
                x=a*x+c
                return x
        end
end

http://www.library.cornell.edu/nr/bookcpdf/c7-1.pdf

This is suitable for 32-bit integers.

--lhf
Reply | Threaded
Open this post in threaded view
|

RE: Math.Random() always returns 0

Richard Ranft
In reply to this post by Incley, Mark

> By using the
> D3DCREATE_FPU_PRESERVE option when creating the D3D device, the
> math.random problem vanished.

What performance impact - if any - has this caused?  Microsoft's docs
mention an unspecified performance hit and I'm wondering if anyone has
actually noticed how bad (or not) that it is.

Richard

Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

Adam D. Moss
Richard Ranft wrote:
>> By using the
>> D3DCREATE_FPU_PRESERVE option when creating the D3D device, the
>> math.random problem vanished.
>
> What performance impact - if any - has this caused?  Microsoft's docs
> mention an unspecified performance hit and I'm wondering if anyone has
> actually noticed how bad (or not) that it is.

This question keeps coming round.  IIRC someone on this list (or
maybe it was the ODE list) finally did actually try it and the
difference was unmeasurable.

--adam
Reply | Threaded
Open this post in threaded view
|

RE: Math.Random() always returns 0

Incley, Mark
In reply to this post by Beric Holt
For my project, I didn't notice any difference in performance from using
D3DCREATE_FPU_PRESERVE. That's on a pretty modest set up (Win XP SP2,
P3-1Ghz, GeForce 4 TI-4200).

If I get chance I'll do some "before" and "after" D3DCREATE_FPU_PRESERVE
benchmarks and post the results here.

Cheers,
Mark.

-----Original Message-----
From: [hidden email]
[mailto:[hidden email]] On Behalf Of Richard Ranft
Sent: 24 May 2006 14:29
To: Lua list
Subject: RE: Math.Random() always returns 0


> By using the
> D3DCREATE_FPU_PRESERVE option when creating the D3D device, the
> math.random problem vanished.

What performance impact - if any - has this caused?  Microsoft's docs
mention an unspecified performance hit and I'm wondering if anyone has
actually noticed how bad (or not) that it is.

Richard

Reply | Threaded
Open this post in threaded view
|

RE: Math.Random() always returns 0

Richard Ranft
In reply to this post by Adam D. Moss

> This question keeps coming round.  IIRC someone on this list (or
> maybe it was the ODE list) finally did actually try it and the
> difference was unmeasurable.

Thanks - that was the conclusion I was developing myself.  Perhaps it's
worse depending on drivers....

Anyway, nice to know.

Richard

Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

jose marin2
In reply to this post by Luiz Henrique de Figueiredo
Overflow could be a problem in this algorithm?
If x became near MAX_INT, what happens on the next
multiplication ?

--- Luiz Henrique de Figueiredo
<[hidden email]> escreveu:

> BTW, there's always a simple replacement for rand()
> suggested by Knuth,
> as quoted in Numerical Recipes:
>
> do
> local x=0
> local a=1664525
> local c=1013904223
> function randomseed(s)
> x=s
> end
> function rand()
> x=a*x+c
> return x
> end
> end
>
> http://www.library.cornell.edu/nr/bookcpdf/c7-1.pdf
>
> This is suitable for 32-bit integers.
>
> --lhf
>


__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/ 
Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

David Jones-2
In reply to this post by Richard Ranft

On May 24, 2006, at 14:28, Richard Ranft wrote:

>
>> By using the
>> D3DCREATE_FPU_PRESERVE option when creating the D3D device, the
>> math.random problem vanished.
>
> What performance impact - if any - has this caused?  Microsoft's docs
> mention an unspecified performance hit and I'm wondering if anyone has
> actually noticed how bad (or not) that it is.

D3DCREATE_FPU_PRESERVE correctly preserves the FPU state.  Without it,
the state is not preserved.

One is correct, the other is not.  Who cares about the performance
impact.

David Jones

Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

Alex Queiroz
In reply to this post by jose marin2
Hallo,

On 5/24/06, Jose Marin <[hidden email]> wrote:
> Overflow could be a problem in this algorithm?
> If x became near MAX_INT, what happens on the next
> multiplication ?
>

     You could use x=a*x+c % VERY_LARGE_INT, but of course the numbers
will wrap.

--
-alex
http://www.ventonegro.org/
Reply | Threaded
Open this post in threaded view
|

Re: Math.Random() always returns 0

Luiz Henrique de Figueiredo
In reply to this post by jose marin2
> Overflow could be a problem in this algorithm?
> If x became near MAX_INT, what happens on the next
> multiplication ?

That's a congruential generator with modulus MAX_INT.
The whole point is to allow and exploit overflow.
--lhf
Reply | Threaded
Open this post in threaded view
|

RE: Math.Random() always returns 0

Beric Holt
In reply to this post by Beric Holt
Thanks everyone for the feedback.

I've added the D3DCREATE_FPU_PRESERVE flag which solves the problem
perfectly.  I did some rather unscientific benchmarking (eyeballing the
FPS counter) with and without the flag and I didn't see any performance
hit.  Then again, I'm working with a pretty low polygon count and not
doing much with projection matricies.

I'm still quite keen to look into the alternative Random functions in
the future, but at this stage my time is better spent elsewhere on the
project.

Can anyone comment on what has changed between lua v5.02 and v5.1 to
cause the functionality of the math.random() function to change?

Cheers
Beric Holt
Soap Dragon
http://buzzrick.emedia.net.nz 


>I experienced the exact same thing when I upgraded InkSpector
>(Windows/DirectX) from Lua 5.0 to 5.1. By using the
>D3DCREATE_FPU_PRESERVE option when creating the D3D device, the
>math.random problem vanished.

>View this message for more info
>http://lua-users.org/lists/lua-l/2006-01/msg00348.html

>Cheers,
>Mark.

Reply | Threaded
Open this post in threaded view
|

D3DCREATE_FPU_PRESERVE

Richard Ranft
In reply to this post by David Jones-2

> D3DCREATE_FPU_PRESERVE correctly preserves the FPU state.  Without it,
> the state is not preserved.
>
> One is correct, the other is not.  Who cares about the performance
> impact.

If it's a 30% reduction in performance I bet you'd care.  Microsoft wouldn't
have mentioned it if it had not been an issue at some point.

As far as "correct" goes, there is more than one way to skin a cat.  I'm
certain that with a little creative assembly (maybe not that drastic, since
Luiz mentioned another alternative) the FPU state can be pushed and popped
around the Lua VM process, the D3D render/math processing, or both.

It is the simplest fix, no doubt about it.  And if it's <1% we're talking
about in almost all cases then that's awesome.  I'd just hate to find out
that it's 10% or more in a significant portion of cases on reasonably
popular hardware....

Richard

Reply | Threaded
Open this post in threaded view
|

Re: D3DCREATE_FPU_PRESERVE

David Morris-Oliveros-2
Richard Ranft wrote:

>> D3DCREATE_FPU_PRESERVE correctly preserves the FPU state.  Without it,
>> the state is not preserved.
>>
>> One is correct, the other is not.  Who cares about the performance
>> impact.
>>    
>
> If it's a 30% reduction in performance I bet you'd care.  Microsoft wouldn't
> have mentioned it if it had not been an issue at some point.
>
> As far as "correct" goes, there is more than one way to skin a cat.  I'm
> certain that with a little creative assembly (maybe not that drastic, since
> Luiz mentioned another alternative) the FPU state can be pushed and popped
> around the Lua VM process, the D3D render/math processing, or both.
>
> It is the simplest fix, no doubt about it.  And if it's <1% we're talking
> about in almost all cases then that's awesome.  I'd just hate to find out
> that it's 10% or more in a significant portion of cases on reasonably
> popular hardware....
>
> Richard
>  

You'd be amazed at what CPU budgets are on some projects - my entire
work has to fit within 0.5% CPU, and that's an important part of the
game... So any optimizations that can be made, are made, and they can
only be made if we know about the impact.

Reply | Threaded
Open this post in threaded view
|

RE: D3DCREATE_FPU_PRESERVE

Dominic Wong
In reply to this post by Richard Ranft
>You'd be amazed at what CPU budgets are on some projects - my entire
>work has to fit within 0.5% CPU, and that's an important part of the
>game... So any optimizations that can be made, are made, and they can
>only be made if we know about the impact.

Yeah but if that flag causes a performance hit outside your code, surely
that will decrease your percentage of frame time?
Reply | Threaded
Open this post in threaded view
|

RE: D3DCREATE_FPU_PRESERVE

Richard Ranft
> >You'd be amazed at what CPU budgets are on some projects - my entire
> >work has to fit within 0.5% CPU, and that's an important part of the
> >game... So any optimizations that can be made, are made, and they can
> >only be made if we know about the impact.
>
> Yeah but if that flag causes a performance hit outside your code, surely
> that will decrease your percentage of frame time?

My whole point to begin with.  While this flag is effective, the real
question is "Is it the best way?"

Personally, I can't throw the performance question to the wind without at
least a little research.  Perhaps going float instead of double as the Lua
number is a faster way.  Maybe it's careful manual manipulation of the FPU
state.  It could be something else that smarter minds than mine will come up
with.  Or maybe it's as fast as anything else you could do.  The only way to
really be sure is to try all approaches and benchmark, benchmark, benchmark.

I'm not really skilled enough to attempt more than a few approaches - those
listed - and I'm not really sure I'm up to the task of creating effective
benchmarks.  Basically, I (and others, apparently) am simply curious to know
if anyone has checked to see exactly what impact this flag creates vs.
changing the Lua number to float, etc.  From what I've heard everyone has
simply adopted the flag, and damn the cost.

Richard

12