I am creating a random number from 1-100, I was looking at some Stackoverflow questions to look for the proper way and I got confused by the many different suggestions.
What is the difference between using this:
int random= (int)(Math.random()*((100-1)+1));
this:
int random= (int)(Math.random()*(100);
and this:
int random= 1+ (int)(Math.random()*((100-1)+1));
int random = (int)(Math.random()*(x);
This sets random equal to any integer between 0 and x - 1.
int random = 1 + (int)(Math.random()*(x);
Adding 1 to the overall expression simply changes it to any integer between 1 and x.
(int)(Math.random()*((100-1)+1))
is redundant and equivalent to
(int)(Math.random()*(100)
So take note that:
1 + (int)(Math.random()*(x) returns an int anywhere from 1 to x + 1
but
(int)(Math.random()*(x + 1) returns an int anywhere from 0 to x + 1.
I recommend that you use Random and nextInt(100) like so,
java.util.Random random = new java.util.Random();
// 1 to 100, the 100 is excluded so this is the correct range.
int i = 1 + random.nextInt(100);
it has the added benefit of being able to swap in a more secure random generator (e.g. SecureRandom). Also, note that you can save your "random" reference to avoid expensive (and possibly insecure) re-initialization.
The first is equivalent to the second. Both will give a random integer between 0 and 99 (inclusive, because Math.random() returns a double in the range [0, 1)). Note that (100-1)+1 is equivalent to 100.
The third, will give an integer between 1 and 100 because you are adding 1 to the result above, i.e. 1 plus a value in the range [0, 100), which results in the range [1, 101).
Related
I was going through some coding exercises, and had some trouble with this question:
From 5 dice (6-sided) rolls, generate a random number in the range [1 - 100].
I implemented the following method, but the returned number is not random (called the function 1,000,000 times and several numbers never show up in 1 - 100).
public static int generator() {
Random rand = new Random();
int dices = 0;
for(int i = 0; i < 5; i++) {
dices += rand.nextInt(6) + 1;
}
int originalStart = 5;
int originalEnd = 30;
int newStart = 1;
int newEnd = 100;
double scale = (double) (newEnd - newStart) / (originalEnd - originalStart);
return (int) (newStart + ((dices - originalStart) * scale));
}
Ok, so 5 dice rolls, each with 6 options. if they are un-ordered you have a range of 5-30 as mentioned above - never sufficient for 1-100.
You need to assume an order, this gives you a scale of 1,1,1,1,1 - 6,6,6,6,6 (base 6) assuming 1 --> 0 value, you have a 5 digit base 6 number generated. As we all know 6^5 = 7776 unique possibilities. ;)
For this I am going to give you a biased random solution.
int total = 0;
int[] diceRolls;
for (int roll : diceRolls) {
total = total*6 + roll - 1;
}
return total % 100 + 1;
thanks to JosEdu for clarifying bracket requirement
Also if you wanted to un-bias this, you could divide range by the maxval given in my description above, and subsequently multiply by your total (then add offset), but you would still need to determine what rounding rules you used.
Rolling a 6 sided die 5 times results in 6^5 = 7776 possible sequences, all equally probable. Ideally you'd want to partition those sequences into 100 groups of equal size and you'd have your [1 - 100] rng, but since 7776 isn't evenly divisible by 100 this isn't possible. The best you can do to minimize the bias is 76 groups mapped to by 78 sequences each and 24 groups mapped to by 77 sequences each. Encode the (ordered) dice rolls as a base 6 number n, and return 1 + (n % 100).
Not only is there no way to remove the bias with 5 dice rolls, there is no number of dice rolls that will remove the bias entirely. There is no value of k for which 6^k is evenly divisible by 100 (consider the prime factorizations). That doesn't mean there's no way to remove the bias, it just means you can't remove the bias using a procedure that is guaranteed to terminate after any specific number of dice rolls. But you could for example do 3 dice rolls producing 6^3 = 216 sequences encoded as the base 6 number n, and return 1 + (n % 100) if n < 200. The catch is that if n >= 200 you have to repeat the procedure, and keep repeating until you get n < 200. That way there's no bias but there's also no limit to how long you might be stuck in the loop. But since the probability of having to repeat is only 16/216 each time, from a practical standpoint it's not really much of a problem.
The problem is there aren't enough random values in 5-30 to map one to one to 1-100 interval. This means certain values are destined to never show up; the amount of these "lost" values depends on the size ratio of the two intervals.
You can leverage the power of your dice in a way more efficient way, however. Here's how I'd do it:
Approach 1
Use the result of the first dice to choose one subinterval from the
6 equal subintervals with size 16.5 (99/6).
Use the result of the second dice to choose one subinterval from the 6 equal sub-subintervals of the subinterval you chose in step one.
Use... I guess you know what follows next.
Approach 2
Construct your random number using digits in a base-6 system. I.E. The first dice will be the first digit of the base-6 number, the second dice - the second digit, etc.
Then convert to base-10, and divide by (46656/99). You should have your random number. You could in fact only use 3 dice, of course, the rest two are just redundant.
This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 9 years ago.
I am very new to Java and I am stuck on this, I am using the formula:
min + (int)(Math.random()*(max-min+1))
and I have to write statements that assign random integers to the variable x in the following ranges
1 < x <= 8
1 being min and 8 being max
Am I correct that it would be 1 + (int)(Math.random()*(8-1+1))?
-5 < x <= 3
3 being min and -5 being max
and this would be 3 + (int)(Math.radom()*(-5-3+1))?
Any help would be greatly appreciated.
You want a formula to take a real number in the range [0..1), and return an integer in the range [1..8].
When random() picks a real number it the range [0..1),
and you multiply it by 8,
you get a value in the range [0.0 .. 8.0).
Then you then convert to (int), you have an integer in the range [0 .. 7],
because conversion to (int) rounds using the 'floor' step function.
Add one.
use following code. It will generate nos between 0 and max value supplied.
Random generator = new Random(); //Creates a new random number generator
for(int i=0; i<100; i++){
/**
*Returns a pseudorandom, uniformly distributed int value
* between 0 (inclusive) and the specified value (exclusive), drawn from
* this random number generator's sequence
*/
System.out.println(generator.nextInt(100));
}
Get random value with range ( min, max ] , this is the same with the question.
If JDK 1.7 version is used, then you can use one line code to implement such function:
ThreadLocalRandom.current().nextInt(min, max)+1
If JDK version is under 1.7, we can implement it using the following way.
Random random = new Random();
random.nextInt(max - min) + min +1;
2.Get random value with range [ min, max )
Use,
ThreadLocalRandom.current().nextInt(min, max)
or
random.nextInt(max - min) + min ;
Math.random() gives you between 0 and 1. Multiply this by your range, the size of the range, not the absolute value. If you want 1-10 that's 9, if you want 0-10 that's 10, if you want 5-7 that's 2, etc.
Then add or subtract to go from 0 to the starting value.
If you want 0-9 then you're done (you should have multiplied by 9 in the previous step)
If you want 1-10 then add 1
If you want -5 to 5 then subtract 5
If you want 5-7 then do (Math.random()*2)+5;
So I need to output Random numbers between -50 and +50 using Java Standard Collections
These are then to be input into an ArrayList and sorted first ascending and 2nd time descending.
The Input and Sorting I Know how to do, but How can I generate random numbers between -50 and 50, considering these have to be input by a for do loop, one-by-one into an ArrayList
N.B. this question was for an exam, so even though the for-do loop (as an iterative) causes overheads I still need to follow these guidelines.
Thanks a lot
You can generate random number within a range start with 0 like this :
Random randomGenerator = new Random();
int randomInt=randomGenerator.nextInt(101); //This function generate number in range 0 to 100.
randomInt -= 50; //It will give you number between -50 to 50
If you want integers, then Random.nextInt will do it.
myRandom.nextInt(101) - 50
should produce a pseudo-rangom integer using a flat distribution in [-50, 50].
public int nextInt(int n)
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence. The general contract of nextInt is that one int value in the specified range is pseudorandomly generated and returned. All n possible int values are produced with (approximately) equal probability.
another way as well
to produce a random double :
Math.random()
to produce a random double less than 100 for example
Math.random()*100
you can cast the result to any numerical type yu want
you can produce a your result like this
double r = Math.random()*50
if(r % (int)(Math.random()*10 == 2){
r = r*-1;
}
something like that
I want to create randomally number with 16 digits in java.
I can do it with String and after that convert to Long.
there is other option?
Thanks!
You can use the Java class Random to generate random Longs, like here for numbers up to one million:
final long MAX_NUMBER_YOU_WANT_TO_HAVE = 9999999999999999L;
final long MIN_NUMBER_YOU_WANT_TO_HAVE = 1000000000000000L;
Long actual = Long.valueOf(Math.abs(Float.valueOf(new Random().nextFloat() * (MAX_NUMBER_YOU_WANT_TO_HAVE - MIN_NUMBER_YOU_WANT_TO_HAVE)).longValue()));
If you absolutely need 16 digits (not a number from 0 to 10^17-1)
Random rand = new Random;
long accumulator = 1 + rand.nextInt(9); // ensures that the 16th digit isn't 0
for(int i = 0; i < 15; i++) {
accumulator *= 10L;
accumulator += rand.nextint(10);
}
I might have an off-by-one on the for loop, use i < 16 if need be.
Your reason for wanting 16 digits is probably key here.
If you only want a number possibly as big as the biggest 16-digit number, then use your favored random number generator to generate a random number between 0 and 9 999 999 999 999 999. You can then add leading zeroes as needed to display exactly 16 characters if that's the reason.
If you explicitly want there to be 16 decimal digits and the first one cannot be zero, you can try the same exercise with 999 999 999 999 999 as upper bound instead and add a random digit from 1 to 9 in front (multiply it by a quadrillion and then sum with the other random number, if need be).
There's plenty of other options, but those are probably the most obvious and simple to implement. I'm quite sure there are native facilities in Java for generating random long numbers.
I want to generate a random number of 14 positive digits only and I use the below function for it:
public void random()
{
Random number = new Random();
long l = number.nextLong();
number.setSeed(System.currentTimeMillis());
long num = Math.abs(number.nextInt())%999 + (l/100000); // problematic line
mTextBox.setString("" + num);
}
I very new to to JavaMe, I have made above function myself but I believe it is not working as expected. It also generates -ve numbers. Also sometimes one or two digits are missing in generated number resulting in 12 or 13 numbers not 14.
Any suggestions or improvement to the code will be highly appreciated.
If you want 14 digits, then you should use 14 calls to number.nextInt(10) - something like this:
public static String randomDigits(Random random, int length)
{
char[] digits = new char[length];
// Make sure the leading digit isn't 0.
digits[0] = (char)('1' + random.nextInt(9);
for (int i = 1; i < length; i++)
{
digits[i] = (char)('0' + random.nextInt(10));
}
return new String(digits);
}
Note that I've made the instance of Random something you pass in, rather than created by the method - this makes it easier to use one instance and avoid duplicate seeding. It's also more general purpose, as it separates the "use the string in the UI" aspect from the "generate a random string of digits".
I don't know whether Random.nextInt(int) is supported on J2ME - let me know if it's not. Using Math.abs(number.nextInt())%999 is a bad idea in terms of random distributions.
I didn't understand what you really want, the code suggests that you want a 3 digit number (%999).
Otherwise you can create a 14 digit number between 1000000000000000 and 9999999999999999 by
long num = 1000000000000000L + (long)(number.nextDouble() * 8999999999999999.0);
note (1 / 100000) is 0 (zero) since it is done by integer division, use (1.0 / 100000.0) for double division
long num = 10000000000000L+(long)(random.nextDouble()*90000000000000.0);
EDIT:
mTextBox.setString(MessageFormat.format("{0,number,00000000000000}",
new Object[] {new Long(num)}));
You are getting negative numbers because Random.nextInt() returns any 32-bit integer, and half of them are negative. If you want to get only positive numbers, you should use the expression Random.nextInt() & 0x7fffffff or simply Random.nextInt(10) for a digit.