How to generate random values between -1/2 to 1/2 - java

I am trying to figure out a way to generate random values between 1/2 and -1/2.
I tried something as below, but not sure if this is a right way to do it....
Can someone please let me know a good way to implement this?
public static void main(String args[]) {
double Max = .5;
double Min = -0.5;
for (int i = 0; i < 10000; i++) {
double value = Min + ((Math.random()) * (Max - Min));
System.out.println(value);
}
}

Well Math.random() returns a random double between 0 and 1, so to change the range to -1/2 to 1/2, we can just subtract 1/2 (since 0 - 1/2 = -1/2 and 1 - 1/2 = 1/2):
Math.random() - 0.5
What you are doing now is more general, i.e. if you want a double between min and max the appropriate expression would be
min + Math.random() * (max - min)
In this case, plugging in min = -0.5 and max = 0.5 we have
-0.5 + Math.random() * (0.5 - -0.5)
which simplifies to
Math.random() - 0.5
I should also mention that, if you read the random() method's documentation, you will find that it returns a double greater than or equal to 0.0 and less than 1.0. This means that the expression above should produce a number in the range [-0.5, 0.5), meaning that -0.5 can potentially be returned but 0.5 cannot be.

You could just do:
Math.random() - 0.5
This is because the min of Math.random() is 0, and the max is 1. If you subtract a half, the min will be 0 - 0.5 == -0.5 and the max will be 1 - 0.5 == 0.5.
Therefore, your original code can be shortened to:
public static void main(String args[]) {
for (int i = 0; i < 10000; i++) {
double value = Math.random() - 0.5; // no need for a "double" cast,
// Math.random() returns a double
System.out.println(value);
}
}

Bear in mind that the Math.Random() class is going to return a value between 0 and 1, not including 1.
In this case, Math.Random()-0.5 will work sweetly

Related

Need to generate random numbers between two values ignoring the given values

I need to generate random numbers using Math.random() between two given values but ignoring on this comparation the two given values or just one depending the case.
Those are the values to do:
Between -7 and 0, excluding 0.
Between 0 and 4, both of the values excluded.
Between 4 and 5, excluding 4.
I've tried with the first case the following code:
double fv = (-7) + Math.random() * (0 -7);
System.out.println(fv);
But it's giving me weird resoults like -13.00123.
It's for a degree excercise so I have to keep it simple.
Any ideas?
The correct formula for random numbers in a range is Min + (Math.random() * (Max - Min)) (including lower bound and excluding upper bound).
For your numbers the correct way would be
double fv = (-7) + Math.random() * (0 - -7);
Since you used only one - in the formula the Minvalue was assumed to be 7 and not -7 which leads to wrong results.
double fv = (-7) + Math.random() * 7;
System.out.println(fv);
creates a random double between (and including) 0.0 and 1.0 (excluding the 1.0 itself). Multiplying by 7 makes a hypothetical range of 0 to 6.99[...]9. Subtracting by 7 makes a the range of the random number from -7 to 0.00[...]01
You can use this information to deduct the formulas for your desired random numbers in a similar way.
Try this
Random random = new Random();
random.ints(1, -7, 0).forEach(System.out::println);
Last value in ints() method will be excluded.
You can set-up an enum to determine inclusivity.
import java.util.concurrent.ThreadLocalRandom;
public class RandomUtil {
private enum Inclusivity { INCLUSIVE, EXCLUSIVE; }
public static double randomDouble(double minValue, double maxValue) {
return randomDouble(minValue, maxValue, Inclusivity.INCLUSIVE, Inclusivity.EXCLUSIVE);
}
public static double randomDouble(double minValue, double maxValue, Inclusivity minInclusivity, Inclusivity maxInclusivity) {
if (minInclusivity == Inclusivity.EXCLUSIVE) {
minValue += 1;
}
if (maxInclusivity == Inclusivity.INCLUSIVE) {
maxValue += 1;
}
return ThreadLocalRandom.current().nextDouble(minValue, maxValue);
}
public static void main(String[] args) {
System.out.println(randomDouble(-7, 0, Inclusivity.INCLUSIVE, Inclusivity.EXCLUSIVE)); // default
System.out.println(randomDouble( 0, 4, Inclusivity.EXCLUSIVE, Inclusivity.EXCLUSIVE));
System.out.println(randomDouble( 4, 5, Inclusivity.EXCLUSIVE, Inclusivity.INCLUSIVE));
}
}
Generate a number between -7 and 0 excluding 0.
double w = (Math.random() - 1) * 7;
When the random number = 0, the required value will be -7. But the required value but will never be 0 since Math.random() will never be 1.
For the others
// between 0 and 4 both values excluded.
double r = Math.random();
double x = (-3 * r); // -3 < x <= 0
double xx = r + 3; // 3 <= xx < 4
x += xx; // 0 < x < 4
// between 4 and 5 excluding 4
double w = (-1 * Math.random()); // -1 < w <= 0
w += 5; // 4 < w <= 5

Generate random float, both bounds inclusive

I need to generate random real numbers in the range [-0.5, 0.5], both bounds inclusive.
I found various ways to generate similar ranges, like
-0.5 + Math.random()
But the upper bound is always exclusive, I need it inclusive as well. 0.5 must be inside the range.
One way to achieve this would be to create random int from -500 to 500 and then divide it by 1000.
int max = 500;
int min = -500;
int randomInt = rand.nextInt((max - min) + 1) + min;
float randomNum = randomInt / 1000.00f;
System.out.println(randomNum);
You can change the precision by adding and removing zeros from the integer boundaries and the divisor. (eG: create integers from -5 to +5 and divide by 10 for less precision)
A disadvantage of that solution is that it does not use the maximum precision provided by float/double data types.
I haven't seen any answer that uses bit-fiddling inside the IEEE-754 Double representation, so here's one.
Based on the observation that a rollover to a next binary exponent is the same as adding 1 to the binary representation (actually this is by design):
Double.longBitsToDouble(0x3ff0000000000000L) // 1.0
Double.longBitsToDouble(0x3ffFFFFFFFFFFFFFL) // 1.9999999999999998
Double.longBitsToDouble(0x4000000000000000L) // 2.0
I came up with this:
long l = ThreadLocalRandom.current().nextLong(0x0010000000000001L);
double r = Double.longBitsToDouble(l + 0x3ff0000000000000L) - 1.5;
This technique works only with ranges that span a binary number (1, 2, 4, 8, 0.5, 0.25, etc) but for those ranges this approach is possibly the most efficient and accurate. This example is tuned for a span of 1. For ranges that do not span a binary range, you can still use this technique to get a different span. Apply the technique to get a number in the range [0, 1] and scale the result to the desired span. This has negligible accuracy loss, and the resulting accuracy is actually identical to that of Random.nextDouble(double, double).
For other spans, execute this code to find the offset:
double span = 0.125;
if (!(span > 0.0) || (Double.doubleToLongBits(span) & 0x000FFFFFFFFFFFFFL) != 0)
throw new IllegalArgumentException("'span' is not a binary number: " + span);
if (span * 2 >= Double.MAX_VALUE)
throw new IllegalArgumentException("'span' is too large: " + span);
System.out.println("Offset: 0x" + Long.toHexString(Double.doubleToLongBits(span)));
When you plug this offset into the second line of the actual code, you get a value in the range [span, 2*span]. Subtract the span to get a value starting at 0.
You can adjust the upper bound by the minimal value (epsilon) larger than the maxium value you expect. To find the epsilon, start with any positive value and make it as small as it can get:
double min = -0.5;
double max = 0.5;
double epsilon = 1;
while (max + epsilon / 2 > max) {
epsilon /= 2;
}
Random random = ThreadLocalRandom.current();
DoubleStream randomDoubles = random.doubles(min, max + epsilon);
Edit: alternative suggested by #DodgyCodeException (results in same epsilon as above):
double min = -0.5;
double max = 0.5;
double maxPlusEpsilon = Double.longBitsToDouble(Double.doubleToLongBits(max) + 1L)
Random random = ThreadLocalRandom.current();
DoubleStream randomDoubles = random.doubles(min, maxPlusEpsilon);
Given HOW GOD SPIDERS answer, here is a ready to use function :
public static double randomFloat(double minInclusive, double maxInclusive, double precision) {
int max = (int)(maxInclusive/precision);
int min = (int)(minInclusive/precision);
Random rand = new Random();
int randomInt = rand.nextInt((max - min) + 1) + min;
double randomNum = randomInt * precision;
return randomNum;
}
then
System.out.print(randomFloat(-0.5, 0.5, 0.01));
#OH GOD SPIDERS' answer gave me an idea to develop it into an answer that gives greater precision. nextLong() gives a value between MIN_VALUE and MAX_VALUE with more than adequate precision when cast to double.
double randomNum = (rand.nextLong() / 2.0) / Long.MAX_VALUE;
Proof that bounds are inclusive:
assert (Long.MIN_VALUE/2.0)/Long.MAX_VALUE == -0.5;
assert (Long.MAX_VALUE/2.0)/Long.MAX_VALUE == 0.5;
Random.nextDouble gives a value in the range of [0, 1]. So to map that to a range of [-0.5, 0.5] you just need to subtract by 0.5.
You can use this code to get the desired output
double value = r.nextDouble() - 0.5;

Random number with negative min or max and with 0.5 as possible decimal

So basically I need to generate a number between a min and max (could be negative as well) and there should be a possibility the number could end with a decimal 0.5.
So, for example, the numbers could be 5, 6, -8.5, 3.5.
I have this to generate my number (example):
rand.nextInt(20 + 1 + 10) - 10;
You could generate an integer with twice the range you want, and then halve it.
Something like this:
int min = -5;
int max = 15;
double r = min + 0.5 * rand.nextInt(2 * (max - min));
If you want max included in the random range, then:
double r = min + 0.5 * rand.nextInt(2 * (max + 1 - min));
Math.round((min + (rand.nextDouble() * Math.abs(max - min))) / 0.5) * 0.5;
should do the trick by creating a correct value in range [min, max] (including both min and max as possible values!)

Creating Minimum Value with Random Operator in Java

I need to generate a random number that is between a minimum value and 1 -> [min, 1)
I have been reading over the random class of java, and have found that when generating a random double, the result is a double from 0 to 1.0, however, you cannot limit the bound.
My original thought was to limit the top value of the random function to .7, but this is not possible with the random function.
If anyone could help me here's my code:
public static double random(){
// generate an random number accuracy within range [min, 1)
Random randomNum = new Random();
double accuracy = min + randomNum.nextDouble();
System.out.println("Min " + min);
return accuracy;
}
If for example we take min to be .2 in this case, then the possible results of the function as I understand are .2 to 1.2. How can I make it simply .2 to 1?
Correct me if I'm wrong, but wouldn't this work:
public static double random(int min, int max){
Random randomNum = new Random();
return (max - min) * randomNum.nextDouble() + min;
}
Explanation:
(max - min) returns the difference between max and min.
randomNum.nextDouble() returns a random number between 0 and 1
+ min will add the min value so it's the lowest value
(max - min) * randomNum.nextDouble() returns a random number between 0 and max-min
(max - min) * randomNum.nextDouble() + min returns a random number between min and max
/**
* A double uniformly distributed in the range [min, max).
* #param min finite and inclusive.
* #param max finite, > min, and exclusive.
* #return d such that min <= d && d < max.
*/
public static boolean uniformInRange(double min, double max, Random r) {
assert min < max && !Double.isInfinite(min) && !Double.isInfinite(max);
return min + (r.nextDouble() * (max - min));
}
To use it, just call
uniformInRange(min, 1.0d, randomNum)
What about something like this?
double min = .2;
Random gen = new Random();
double rand = (gen.nextDouble() * 0.8) + min;
Here you are adding the min bound at the end, and multiplying your 0-1 ratio by 0.8, which is the difference between 0.2 and 1.

Java Random double in interval [-1000, 1000]

In java I have:
Random random = new Random();
double randomNum = random.nextDouble();
which creates a random number between 0 and 1. However I want a number between -1000 and 1000, how would I scale this?
Thanks
2 possibilities:
[less dense]: multiple your results by 2000, and subtract 1000
from the result. It won't be as 'dense' as possibility 2.
get a random int in range [-1000,999], and add a random double in
range [0,1].
Note that possibility 2 ensures better randomness and better 'density' of your numbers, at the cost of 2 random calls [which might be expansive, if it is an issue].
Um, maths?
double randomNum = (random.nextDouble()-0.5d) * 2000;
Random random = new Random();
double randomNum = (random.nextDouble() * 2000.0d) - 1000.0d;
Try this algorithm:
Generate a random value in the range 0 to 1.
multiply that value by 2000 (the size of the desired range).
subtract 1000 from the result of step 2 (move the value into the desired range).
This gives you a number on that range
double randomNum = (random.nextDouble() * 2000) -1000;
Here is a general function you could use to linearly rescale a number between zero and one (val01) to a different range (min..max):
public static double rescale(double val01, double min, double max) {
return val01 * (max - min) + min;
}
public static double doubleBetween(double start, double end) {
Random random = new Random();
// We need 64 bits because double have 53 bits precision, so int is too short
// We have now a value between 0 and Long.MAX_VALUE.
long value = -1L;
while (value < 0)
value = Math.abs(random.nextLong()); // Caution, Long.MIN_VALUE returns negative !
// Cast to double
double valueAsDouble = (double) value;
// Scale so that Long.MAX_VALUE is exactly 1 !
double diff = (end-start)/(double) Long.MAX_VALUE;
return start + valueAsDouble*diff;
}
This will give the correct interval including both ends with full double precision. doubles have a special -0.0 value (the negative zero) which will not be given by this routine.
Random random = new Random();
int randomNum = random.nextInt(2000) - 1000;
public static double randomInterval(double minValue,double maxValue){
Random random = new Random();
double r;
do {
r = random.nextDouble();
} while (r < minValue || r >= maxValue);
return r;
}
Example :
double a = randomInterval(-1000,1000) ;

Categories

Resources