Page 1 of 3

Randomly choose negative or positive while excluding zero

Posted: Sat May 26, 2012 4:26 am
by Jasoco
Anyone have a better easier way to randomly choose between -1 and 1 (Positive and negative) than what I've come up with so far?

One way of doing it

Code: Select all

local num = math.random(0,1)
if num == 0 then num = -1 end
One I just came up with

Code: Select all

local neg = { -1, 1 }
num = neg[math.random(1,2)]
Surely there's a different way, or is this the best way?

Re: Randomly choose negative or positive while excluding zer

Posted: Sat May 26, 2012 5:25 am
by Boolsheet
There's also:

Code: Select all

num = math.random() >= 0.5 and 1 or -1
They all perform about the same.

What do you mean by 'the best way'? Best way to do what?

Re: Randomly choose negative or positive while excluding zer

Posted: Sat May 26, 2012 8:46 am
by Jasoco
I dunno. Most efficient and least "hacky". There's always someone who will say "You're coding the silly way" when looking at another person's code.

Re: Randomly choose negative or positive while excluding zer

Posted: Sat May 26, 2012 8:49 am
by bartbes
I used to do stuff like math.random(0, 1)*2-1.

Re: Randomly choose negative or positive while excluding zer

Posted: Sat May 26, 2012 11:06 am
by Robin
bartbes wrote:I used to do stuff like math.random(0, 1)*2-1.
Yeah, I'd do that too.

Re: Randomly choose negative or positive while excluding zer

Posted: Sat May 26, 2012 11:49 am
by Boolsheet
Jasoco wrote:"You're coding the silly way"
The only way to enjoy the quirks of programming languages. ;)
In this case, the winner is probably what's most readable to you.

Using a table uses up some memory and it has an average speed.
If you want speed, then something like this wins (not by much):

Code: Select all

local c
if math.random() >= 0.5 then -- Instead of math.random there would be a local variable pointing to the function.
    c = 1
else
    c = -1
end
Specifying a range for math.random makes Lua do more work and 'if .. then .. end' is faster than the ternary-style '... and ... or ...'.

Re: Randomly choose negative or positive while excluding zer

Posted: Sat May 26, 2012 1:03 pm
by coffee
Well, without doubt bartbes and Robin's way is much more clever, short and faster. But I end to prefer a more long, "legible" as the second method from Jasoco. Don't know, feels like the correct cleaner (but not the efficient coder) way to do.

Code: Select all

rnd = choose({-1,1})
function choose(t)
    return t[math.random(1,2)]
end
EDITED:
Thank you Jasoco, at the end I made a handy table random element selector.

Code: Select all

function choose(t)
    if t[1] then return t[math.random(1,#t)]
end

Re: Randomly choose negative or positive while excluding zer

Posted: Sat May 26, 2012 2:03 pm
by Boolsheet
coffee wrote:faster
Faster to write maybe, but not faster in execution. ;)

Re: Randomly choose negative or positive while excluding zer

Posted: Sat May 26, 2012 9:07 pm
by dreadkillz
I was thinking of using a while loop:

Code: Select all

local num = math.random(-1,1)
while num == 0 do
 num = math.random(-1,1)
end

Re: Randomly choose negative or positive while excluding zer

Posted: Sat May 26, 2012 9:26 pm
by coffee
dreadkillz wrote:I was thinking of using a while loop:

Code: Select all

local num = math.random(-1,1)
while num == 0 do
 num = math.random(-1,1)
end
Don't seem good code spite of work. So the program will hang in loop till haven't the luck of not be a zero?