Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate random numbers which will provide proper results on division

Tags:

java

math

decimal

How to generate random numbers which will provide proper results on division (i.e the results should round to exactly 1 or 2 places after the decimal point).

(e.g a whole number by a decimal number providing decimal results - I have given a set of sample inputs below)

2827 by 2.5 = 1130.8
1747 by 0.8 = 2183.75
425 by 0.4 = 1062.5
935 by 0.8 = 1168.75
like image 269
Joe Avatar asked May 13 '11 13:05

Joe


People also ask

What is the best method to generate true random numbers?

To generate “true” random numbers, random number generators gather “entropy,” or seemingly random data from the physical world around them. For random numbers that don't really need to be random, they may just use an algorithm and a seed value.

How can we generate the random numbers?

A true random number generator (TRNG), also known as a hardware random number generator (HRNG), does not use a computer algorithm. Instead, it uses an external unpredictable physical variable such as radioactive decay of isotopes or airwave static to generate random numbers.

What two methods will we use to generate random numbers?

There are two main approaches to generating random numbers using a computer: Pseudo-Random Number Generators (PRNGs) and True Random Number Generators (TRNGs). The approaches have quite different characteristics and each has its pros and cons.


2 Answers

res = input * random.nextInt (100) / 100.0;

Explanation:

You take a whole number n, and multiply it with something. If this something is a number like 34.56, we call the part before the decimal digit w (whole part) and the part behind .xy.

If you multiply this with n, you end with (n*w)+(n*(x/10))+n*(y/100). There will never be an fractional part 3 ciphers behind the dot - do you agree?

We can combine x and y to a single part, and say (n*w) + (n*(xy/100)), and xy is just the name for something from 0 to 100.

Since the part before the decimal dot can be arbitrary large, you can calculate it seperately, if you need something else than 0. But you have to define a range somehow. If you take an random Integer R for that part:

res = input * R * random.nextInt (100) / 100.0;

Do you need the divisor explicityl?

div = 100.0 / (R * random.nextInt (100));

Scala is always handy, when testing code fragmenst:

val r = util.Random 
r: util.Random.type = scala.util.Random$@ce2f12

scala> def res (input: Int) = input * r.nextInt (100) / 100.0;
res: (input: Int)Double

scala> (1 to 20).map (res) 
res338: scala.collection.immutable.IndexedSeq[Double] =
Vector(0.48, 1.58, 0.48, 2.8, 0.15, 1.98, 5.67, 3.36, 6.93, 6.0, 9.02, 0.48, 7.41, 6.44, 9.6, 1.92, 16.66, 5.94, 7.98, 18.4)
like image 89
user unknown Avatar answered Oct 14 '22 02:10

user unknown


It is worth noting that all integers can be divided by 0.4, 0.8 or 2.5 and be represented to two decimal places. This is because it is the same as multiplying by 2.5, 1.25, and 0.4


However, if you have a divisor for which this is not true, you can do this in a loop.

double divisor = 2.4;
double factor = 100/divisor;
Random rand = new Random();
int maxValue = 1000;
double ERROR = 1e-14*maxValue;

for(int i=0;i<100;i++) {
long randNum;
do {
   randNum = rand.nextInt(maxValue+1);
    if (Math.abs(randNum * factor - (long) (randNum * factor)) > ERROR)
        System.out.println("reject "+randNum + " => "+randNum/divisor);
} while(Math.abs(randNum * factor - (long) (randNum * factor)) > ERROR);
System.out.println(randNum + " => "+randNum/divisor);

prints

729 => 303.75
285 => 118.75
84 => 35.0
123 => 51.25
999 => 416.25
75 => 31.25
reject 727 => 302.9166666666667
reject 842 => 350.83333333333337
504 => 210.0
reject 368 => 153.33333333333334
441 => 183.75
579 => 241.25
165 => 68.75

This will generate random numbers until you have a number which is a multiple of 0.01.

like image 3
Peter Lawrey Avatar answered Oct 14 '22 02:10

Peter Lawrey