Generate Random X.XXX numbers between [-2, 2] - java

x = rd.nextInt((4000) - 2000) / 1000.0;
This is generating numbers between [0, 2] to the thousandth decimal which is what I want, I just also need negative number so the range of numbers generated is between [-2, 2].

The problem you are facing is integer arithmetic, which truncates the fractional part of the result. Use rd.nextDouble() instead so the arithmetic results are double, which retains the fractional part.
However, to round to 1/100ths, you can use integer arthmetic to your advantage.
Your question has the text to the hundredth decimal, so here's that solution:
x = (int)(((rd.nextDouble() * 4) - 2) * 100) / 100d;
But your title mentions X.XXX, so here's that solution:
x = (int)(((rd.nextDouble() * 4) - 2) * 1000) / 1000d;
To unravel what's going on here:
generate random double between 0.000000 and 1.000000
multiply by the scale of the range, so we get a number between 0.000000 and 4.000000
subtract 2, so we get a number between -2.000000 and 2.000000
multiply by 1000, so we get a number between -2000.000000 and 2000.000000
cast to int to truncate the fraction, so we get a int between -2000 and 2000
divide by 1000d (which is a double), so we get a double between -2.000 and 2.000

Floating point numbers do not always have a precise number of digits. Also, the third decimal place is called thousandths (the hundredth decimal would be the second digit after the .). I think you know this because you are dividing by a thousand. So, step one: generate a single random value between 0 and 4 as a double. Step two: Subtract two and convert to a formatted String (so you can control the number of digits).
double d = (rd.nextDouble() * 4) - 2;
String x = String.format("%.3f", d);

You can generate a random float and then use a modulo to truncate it to the hundredth decimal place.
int min = -2;
int max = 2;
Random rand = new Random();
float ret = rand.nextFloat() * (max - min) + min;
return ret - (ret % 0.01);

You can generate random number on a range [0,4] and then simply subtract 2 from the result:
x = (rd.nextInt(4000) / 1000.0) - 2;

Related

Pretty number formatting algorithm

Algorithm to convert an integer representing a number of bytes into an pretty format.
3 digits max (not counting decimal) - for eg like linux command line.
no leading or trailing zeroes
1K is 1000 bytes
Examples:
Correct
123B -> 123B
12300B -> 12.3K
1910000B -> 1.91M
1000000000B -> 1G
83123 = 83.1K (not 83K)
Incorrect
012K (should be 12K)
8.20M (should be 8.2M)
I would like to know what did I do wrong or is there an easy better way to solve this problem or if there are any bugs in my code.
Below is my solution (it works but I was not selected so I have not idea of what I did wrong) -
/*
* #Description - Function takes integer as input and returns the number in
* pretty format(Gigabyte, Megabytes, KiloBytes, Bytes) with maximum of 3
* digits
* #param integer to convert to pretty format
* #Assumptions - As mentioned in the problem set, 1000bytes = 1KB
* Value is rounded to the nearest valid value
* In java leading 0 in number is considered Octal, this function does not
* take care of octal to decimal conversion
* As 1G = 1,000,000,000B the loop will run maximum 3 times in worst case
* Its requires constant space O(1) to store the result
*/
static String fpretty(int num) {
int count = 0;
double div_result = (double) num;
String display = "";
/*
* Every time we divide by 1000 count is incremented from B->K->M->G
* Here two decimal places are preserved for cases like 1.05, 1.11
* The output result of this loop will have 1,2 or 3 digits with max
* two decimal places
*/
while(div_result > 999.5) {
div_result = div_result / 1000;
div_result = Math.round(div_result * 100.0) / 100.0;
count++;
}
// Get suffix B, K, M or G
String measure = getUnit(count);
// If decimal places is all zeros OR result has 3 digits
if(div_result % 1 == 0 || div_result >= 100)
display = (int)div_result + measure;
// If result has 2 digits
else if (div_result >= 10) {
// Then fetch 1 decimal place as we have 2 digits
div_result = (Math.round(div_result * 10.0) / 10.0);
// If after rounding decimal places are .0 then truncate zeros
// eg. 99.97 rounded to -> 100.0 -> 100
if(div_result % 1 == 0)
display = (int)div_result + measure;
else
display = div_result + measure;
}
else
display = div_result + measure;
return display;
}
This can be done with much less effort using the DecimalFormat class. Let it do the rounding for you, which can be described in a pattern and choose the way of rounding by RoundingMode. It also takes care of the trailing zeros, which will be simply ignored.
public String pretty(int num) {
DecimalFormat f = new DecimalFormat("###.##");
f.setRoundingMode(RoundingMode.HALF_UP);
double prettyd = num;
int count = 0;
while (prettyd >= 1000.0) {
prettyd /= 1000.0;
count++;
}
return f.format(prettyd) + getUnit(count);
}

printing the percent completed

I am trying to divide 2 Long's in order to find the percentage. However, I only get 0.0% or when they are equal, 100.0%. This is what I am doing
long size =
long mem =
double avg = (double)(size / mem) * 100;
You're doing long division which truncates the fractional part of the number. At least one of the operands is required to be a double to produce a non-zero double, You could do:
double avg = (double)size / mem * 100;
The numerator now becomes a double as a cast has high precedence than the division operator /.
If you want to avoid long decimal numbers you can use.
long percentage = 100 * size / mem; // as an integer.
If you want one decimal place you can do
double percentage = (1000 * size / mem) / 10.0;

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

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
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)
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.
If you want the result to 'round' to 2 decimal places (it's not really rounding, it's just a finite decimal representation with two decimal points), then just generate the divisor, and have the dividend always be 100, e.g.:
106250 / 100 = 1062.5
116875 / 100 = 1168.75
If you want more interesting dividends then divide the divisor and dividend. e.g. the first one could be any one of:
(/1): 106250 / 100 = 1062.5
(/2): 53125 / 50 = 1062.5
(/10): 10625 / 10 = 1062.5
(/4): 26562.5 / 25 = 1062.5
(/125): 850 / 0.8 = 1062.5
For me the dividend and divisor are both random numbers. I have to produce an answer which doesn't require rounding decimals beyond 2 decimal places.
If that is the case, the answer might be "there is no such number". Here's a little Java program I wrote to test this hypothesis:
import java.text.DecimalFormat;
public class Test {
public static void main(String[] args) {
double num = Math.PI;
DecimalFormat format = new DecimalFormat(
"####################################0." +
"00##############################");
while (true) {
for (int i = 1; i < Integer.MAX_VALUE; i++) {
double tmp = (i / num) * 100;
if (tmp == (long) tmp) {
System.err.println("Solution - " + i + " - " +
format.format(tmp) + " - " + format.format(num));
break;
}
}
pi = Math.nextAfter(num, 1);
}
System.err.println("No solution for " + format.format(num));
}
}
I ran this for 10 minutes (starting at PI), and didn't find any values of num that had no solution i. But I did observe that solutions can be very sparse. For instance:
Gotcha! - 179453441 - 5712180438.00 - 3.1415926535897714
It took 179 million attempts to find the solution for that divisor.

How to round integer in java

I want to round the number 1732 to the nearest ten, hundred and thousand. I tried with Math round functions, but it was written only for float and double. How to do this for Integer? Is there any function in java?
What rounding mechanism do you want to use? Here's a primitive approach, for positive numbers:
int roundedNumber = (number + 500) / 1000 * 1000;
This will bring something like 1499 to 1000 and 1500 to 2000.
If you could have negative numbers:
int offset = (number >= 0) ? 500 : -500;
int roundedNumber = (number + offset) / 1000 * 1000;
(int)(Math.round( 1732 / 10.0) * 10)
Math.round(double) takes the double and then rounds up as an nearest integer. So, 1732 will become 173.2 (input parameter) on processing by Math.round(1732 / 10.0). So the method rounds it like 173.0. Then multiplying it with 10 (Math.round( 1732 / 10.0) * 10) gives the rounded down answer, which is 173.0 will then be casted to int.
Use Precision (Apache Commons Math 3.1.1)
Precision.round(double, scale); // return double
Precision.round(float, scale); // return float
Use MathUtils (Apache Commons Math) - Older versions
MathUtils.round(double, scale); // return double
MathUtils.round(float, scale); // return float
scale - The number of digits to the right of the decimal point. (+/-)
Discarded because method round(float,
scale) be used.
Math.round(MathUtils.round(1732, -1)); // nearest ten, 1730
Math.round(MathUtils.round(1732, -2)); // nearest hundred, 1700
Math.round(MathUtils.round(1732, -3)); // nearest thousand, 2000
Better solution
int i = 1732;
MathUtils.round((double) i, -1); // nearest ten, 1730.0
MathUtils.round((double) i, -2); // nearest hundred, 1700.0
MathUtils.round((double) i, -3); // nearest thousand, 2000.0
You could try:
int y = 1732;
int x = y - y % 10;
The result will be 1730.
Edit: This doesn't answer the question. It simply removes part of the number but doesn't "round to the nearest".
At nearest ten:
int i = 1986;
int result;
result = i%10 > 5 ? ((i/10)*10)+10 : (i/10)*10;
(Add zero's at will for hundred and thousand).
why not just check the unit digit...
1. if it is less than or equal to 5, add 0 at the unit position and leave the number as it is.
2. if it is more than 5, increment the tens digit, add 0 at the unit position.
ex: 1736 (since 6 >=5) the rounded number will be 1740.
now for 1432 (since 2 <5 ) the rounded number will be 1430....
I hope this will work... if not than let me know about those cases...
Happy Programming,
very simple. try this
int y = 173256457;int x = (y/10)*10;
Now in this you can replace 10 by 100,1000 and so on....
Its very easy..
int x = 1234;
int y = x - x % 10; //It will give 1230
int y = x - x % 100; //It will give 1200
int y = x - x % 1000; //It will give 1000
The above logic will just convert the last digits to 0. If you want actual round of//
For eg. 1278 this should round off to 1280 because last digit 8 > 5 for this i wrote a function check it out.
private double returnAfterRoundDigitNum(double paramNumber, int noOfDigit)
{
double tempSubtractNum = paramNumber%(10*noOfDigit);
double tempResultNum = (paramNumber - tempSubtractNum);
if(tempSubtractNum >= (5*noOfDigit))
{
tempResultNum = tempResultNum + (10*noOfDigit);
}
return tempResultNum;
}
Here pass 2 parameters one is the number and the other is position till which you have to round off.
Regards,
Abhinav
I usually do it this way:
int num = 1732;
int roundedNum = Math.round((num + 9)/10 * 10);
This will give you 1740 as the result.
Hope this will help.
int val2 = 1732;
val2 = (int)(Math.rint((double) i / 10) * 10);
The output is:1730
Have you looked at the implementation of Mathutils.round() ? It's all based on BigDecimal and string conversions. Hard to imagine many approaches that are less efficient.
Without using any math utils, rounding could be achieved to any unit as below:
double roundValue (double input, double toNearest){
//toNearest is any rounding base like 10, 100 or 1000.
double modValue = input % toNearest;
System.out.println(modValue);
if(modValue == 0d){
roundedValue = input;
}
else
{
roundedValue = ((input - modValue) + toNearest);
}
System.out.println(roundedValue);
return roundedValue;
}

Java: Generating a random numbers with a logarithmic distribution

I am attempting to generate a random numbers with a logarithmic distribution.
Where n=1 occurs half of the time, n=2 occurs a quarter of the time, n=3 occurs an eighth of the time, etc.
int maxN = 5;
int t = 1 << (maxN); // 2^maxN
int n = maxN -
((int) (Math.log((Math.random() * t))
/ Math.log(2))); // maxN - log2(1..maxN)
System.out.println("n=" + n);
Most of the time, I am getting the result I need, however once every so often, I get a value of n that is larger than maxN.
Why is this so? The way I see it, the max value of Math.random() is 1.0;
therefore the max value of (Math.random() * t)) is t;
therefore the max value of log2(t) is maxN, since t = 2^maxN;
Where has my logic gone off track?
Thanks
logarithm of numbers less than 1.0 is negative. When the random number generated is such that it is less than 1.0, the expression ((int) (Math.log(Math.random() * t) / Math.log(2))) is a negative number and hence maxN - (the negative number) is more than maxN.
The following expression should give correct distribution.
n = Math.floor(Math.log((Math.random() * t) + 1)/Math.log(2))
Note that:
0.0 <= Math.random() <= 1.0
0.0 <= Math.random() * t <= t
1.0 <= (Math.random() * t) + 1 <= t + 1.0
0.0 <= Math.log((Math.random() * t) + 1) <= Math.log(t + 1.0)
0.0 <= Math.log((Math.random() * t) + 1)/Math.log(2) <= Math.log(t + 1.0)/Math.log(2)
Since t = 2^maxN,
Math.log(t + 1.0)/Math.log(2) is slightly larger than maxN.
So do a Math.floor and you get the correct result:
0.0 <= Math.floor(Math.log((Math.random() * t) + 1)/Math.log(2)) <= maxN
If Math.random()*t is less that 1, then you will get a negative answer when you take Math.log(Math.random()*t), by the rules of Logarithms. This means that you will get a negative answer when you divide by Math.log(2) because that is 0.69314718055994530941723212145818. This is a negative number divided by a positive number. The answer is negative. maxN - a negative number = maxN + something positive, so n is greater than maxN. To fix this cast Math.random()*t to an int and add 1:
int n = maxN -
((int) (Math.log((int)((Math.random() * t)+1))
/ Math.log(2))); // maxN - log2(1..maxN)
Notice the cast inside the log, and the add of 1.
The purpose of adding one would be to avoid the 0. Can't take a log of 0. Also, without adding 1, you could never get maxN inside the log, because Math.random() never produces 1. This way, instead of getting 1 half, 2, a fourth, 3, and eighth, it just starts at 0. This gives 0, a half, 1 a fourth, 2 an eighth, etc.
The problem is in the other end of the scale.
Consider what would happen if you get a very small random number.

Categories