Apex: How to Create a Random Number in a Specific Range

Are you looking for a way to create a random whole number in Apex in a specific range? For instance, between 1 & 10 or 1 & 100 or 7 & 777? If so, here’s the code:

Integer randomNumber = (Integer) Math.random() * (max - min + 1) + min;

As you may have guessed, the min and max represent the range. So, if you wanted a range of 1 to 100, then min = 1 and max = 100. Simple, right? Even so, let’s break it down:

When it comes to random numbers, we typically want an integer (or whole) number. If that’s your case too, then make sure you declare your variable datatype as Integer (just like I did above). Otherwise, you can use Double (a 64-bit-long decimal number), the default value of Math.random().

Here, because we want an integer, I’m also casting the result from a Double to an Integer using the data type name we want in parentheses. (If I didn’t do this, I’d get an error since the variable randomNumber was declared as an Integer.)

Next, we use the random() method from the Math class. This always produces a random number between 0 and 1 (but not including 0 or 1) — for example, this might produce 0.7841714090943729.

Then, we multiply this by (max – min + 1). Using the min and max values from above, this would result in (100 – 1 + 1) or 100. (Yes, you read that right — first we subtracted 1 and then we added it right back! But this only looks ridiculous when min = 1.)

Finally, we take the product from above (Math.random * 100) and add min to it. Again, going with our example, if the random number generated was 0.7841714090943729, then we would multiply that by 100 to get 78.4171409094372900, and then add 1 to get 79.4171409094372900. (Adding min to the final result is like using an offset in a SOQL query. It shifts everything over by a specific number. This allows us to have a range that starts higher than zero.)

After casting the Double to the Integer data type, the final result is 79.

To see this in action, you can copy the code below and run it in the Execute Anonymous Window of the Salesforce dev console or your favorite IDE:

Integer min = 1;
Integer max = 100;
Decimal randomNumber = Math.random();

System.debug('min: ' + min);
System.debug('max: ' + max);
System.debug('Decimal randomNumber = Math.random()');
System.debug('randomNumber: ' + randomNumber);

System.debug('randomNumber * (max - min + 1)');
System.debug(randomNumber + ' * (' + max + ' - ' + min + ' + 1) = ' + randomNumber);
randomNumber *= (max - min + 1);
randomNumber += min;
System.debug('randomNumber + min = ' + randomNumber);
Integer randomNumberInteger = (Integer) randomNumber;
System.debug('(Integer) randomNumber: ' + randomNumberInteger);

Here are my results when running the code:

And there you have it! Now go tweak the min and max in the code above to see if everything is on the up and up!

Want to really test this formula to see if the ranges are working properly? Run the following code and see what it returns in the debug log. You’ll get the frequency of each number returned since multiple random numbers are generated using a loop. Adjust the code as you see fit to see new ranges in action!

Integer min = 10;
Integer max = 20;
Integer repeat = 30; // Determines how many times the loop is repeated

System.debug('min: ' + min + '  |  max: ' + max);

// Generate random numbers (add them to list)
List<Integer> numList = new List<Integer>();
for (Integer i=1; i<=repeat; i++) {
    Integer randomNumber = (Integer) (Math.random() * (max - min + 1) + min);
    numList.add(randomNumber);
}
System.debug('List of random numbers: ' + numList);
numList.sort();

// Create map for each number and its frequency
Map<Integer,Integer> numCountMap = new Map<Integer,Integer>();
for (Integer num : numList){
    if (!numCountMap.keySet().contains(num)) {
        numCountMap.put(num, 1);
    } else {
        numCountMap.put(num, numCountMap.get(num) + 1);
    }
}

// Print results to debug log
System.debug('Number frequency:');
for (Integer num : numCountMap.keySet()) {
    System.debug(num + ': ' + numCountMap.get(num));
}

Did this help you? If so, leave a comment below and let me know!

Note: You’ll often see the Math function floor() used in these types of random number formulas. It looks something like this: Math.floor((Math.random() * max – min + 1) + 1)). This takes the resulting number, say 78.4171409094372900, and rounds it down to the nearest whole number like this: 78.0. If you then cast it to an integer, as we do above, the final result is 78. But we don’t need to round it down first before casting. Casting to the integer data type will automatically strip the decimal portion away, doing the job we employed floor() to do. As a result, we can leave floor() out of the equation.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.