Math.random Keeps Returning the Same Answer


I'm still pretty new to coding and javascript, but I wrote the code below as a three way randomizer. Everything seems to be working fine, except that no matter how many times I run the code the return is whatever is plugged in as "c". I was wondering if anyone can give me some quick advice on what to do to fix this. Thanks.

var random = function() { var randomizer = function() { Math.random() * 100 } if (randomizer <= 33) { var compDecision = "a" } else if (randomizer > 67) { var compDecision = "b" } else if (33 < randomizer <= 67) { var compDecision = "c" } document.write(compDecision) }


A bunch of things come to mind right away:

1. JavaScript doesn't have implicit returns

So this doesn't do what you think:

var randomizer = function() { Math.random() * 100 }

That function returns undefined. You need:

var randomizer = function() { return Math.random() * 100 }

2. Parentheses are not optional in JavaScript function calls

So this <em>also</em> doesn't do what you think:

if (randomizer <= 33) { var compDecision = "a" }

You would need:

if (randomizer() <= 33) { var compDecision = "a" }

3. JavaScript doesn't have three-way comparisons

So this doesn't do what you think:

else if (33 < randomizer <= 67)

You would need:

else if (33 < randomizer() && randomizer() <= 67)

Lastly, as others have mentioned, defining randomizer as a <em>function</em> actually doesn't make sense in the first place. For your random function to do what you want (produce 'a', 'b', or 'c' with roughly equal probability), you really want to produce a single random value at the start of the function and reuse it:

function random() { var randomizer = Math.random() * 100; if (randomizer <= 33) { return 'a'; } else if (randomizer <= 67) { return 'b'; } else { return 'c'; } } console.log(random());

Hopefully that helps.


Dan Tao's answer is great, in addition there doesn't seem to be any point to a one–line function that is only called once, so:

var n = Math.random() * 100;

However, the <em>document.write</em> part probably should be separate as you likely want to call this function in ways where always writing the result to the current document isn't appropriate.

Lastly, you only need test two of the three conditions since if it isn't either of the first two, it must be the third. You use the conditional operator for that:

function random() { var n = Math.random() * 100; return n <= 33? 'a' : n <= 67? 'c' : 'b'; } document.write(random());


You wasn't correctly calling the randomizer function. I've removed it as it wasn't really necessary in this case:

var random = function() { // I assume you want the comparisons below to be run against the same number var randomNumber = Math.random() * 100; if (randomNumber <= 33) { var compDecision = "a"; } else if (randomNumber > 67) { var compDecision = "b" } else { var compDecision = "c" } return compDecision; }


You can simplify your code to this:

<pre class="snippet-code-js lang-js prettyprint-override">var randomizer = Math.random() * 100; if (randomizer <= 33) { var compDecision = "a"; } else if (randomizer > 67) { var compDecision = "b"; } else if (33 < randomizer && randomizer <= 67) { var compDecision = "c"; } alert(compDecision);


randomizer is a variable that is holding a function.

To understand this issue, please try


var value = randomizer(); alert(value);


I think, you can do the same thing way like this:

function Randomize(){ rng = Math.random() * 3; rng = Math.round(rng); switch(rng) { case 0: return "a" break; case 3: return "a" break; case 1: return "b" break; case 2: return "c" break; }; }; alert(Randomize());


JavaScript requires a semicolon after each statement. However, if/then/else shouldn't be followed by a semicolon.

if (a < 10) { alert("Less than ten."); } else { alert("Ten or more."); }

Sometimes semicolons are automatically inserted where they belong, but you shouldn't rely on this -- it's best to type them yourself.


The keyword var is used to create/declare/initialize a variable. This is done only once per variable.

Also it's good practice to declare a variable at the top of the function that contains it.

function() { var result; if (condition1 === true) { result = "a"; } else if (condition2 === true) { result = "b" } else { result = "c" } return result; }


In your code, "randomizer" is a function. To execute it and get the value it returns, you'd have to put a pair of parentheses after it: randomizer()

So randomizer <= 33 isn't comparing two numbers, it's comparing a function to a number. Likewise with randomizer > 67. Each of them therefore evaluates to false.

Then, 33 < randomizer <= 67 evaluates to true. Why? I'm not sure. But because it's considered "true", var compDecision = "c" gets executed.

And that's why you keep getting "c".

<strong>EDIT:</strong> RobG's comment below explains why 33 < randomizer <= 67 evaluates to true in JavaScript.


  • Idiomatic Composing of Monoids
  • Magento - Programmatically create custom product attribute via set up script
  • Can you alter the output of %caller{0} in logback to mimic log4j %l specifier?
  • Using less code for brain teaser
  • Macro to call a function
  • Anonymous functions and Maps in Scala
  • Return value syntax in java
  • dynamic server time
  • Git: failed to read object … Invalid argument
  • Regex failing to match number and dash with letter (or space and letter)
  • How to translate SQL queries to cypher in the optimal way?
  • Can I apply the Git-Flow workflow on GitHub
  • Aspect advising other aspects
  • Can't get LogCat (Alcatel OneTouch Evolve)
  • Defining variable by logical subseting on time interval in data.table
  • Validity Method for Reference Classes
  • Partial specialization of a class template in derived class affects base class
  • C++ Single function pointer for all template instances
  • Retrieving specified columns from a list of csv files to create a data data frame in R
  • Multiple producers single consumer locking schema
  • Fail:(TESTMODE) Transactions of this market type cannot be processed on this system
  • Filter strings with regex before casting to numeric
  • C# program and C++ DLL compiled for 32-bit system crash on 64-bit system
  • Access Android Market through SSH tunnel
  • Excel's Macro-Recorder usage
  • x64 applications using gdi+: what are the consequences on performance?
  • How to use carriage return with multiple line?
  • Custom Tabgroup Appcelerator
  • iOS: Detect app start via notification press
  • Can you perform a UNION without a subquery in SQLAlchemy?
  • jQuery .attr() and value
  • ImageMagick, replace semi-transparent white with opaque white
  • Initializer list vs. initialization method
  • Get object from AWS S3 as a stream
  • Weird JavaScript statement, what does it mean?
  • Rearranging Cells in UITableView Bug & Saving Changes
  • Circular dependency while pushing http interceptor
  • Linker errors when using intrinsic function via function pointer
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • need help with bizarre java.net.HttpURLConnection behavior