For some reason my math just returns 0. The value are set, I have checked.
int currentSize = 4079;
int totalSize = 500802;
int percentage = ((currentSize/totalSize) * 100);
progdialog.setProgress(percentage);
Percentage always equals percentage.
Why?
The problem, as other have pointed out, is integer division will turn anything less than 1 to zero. This happens before multiplying by 100. You can change the order of operations to get something better:
int percentage = currentSize * 100 / totalSize;
If you are concerned about rounding, you can use
int percentage = (currentSize * 100 + (totalSize >> 1)) / totalSize;
These avoid the expense of working with double or float values.
you are using 'int's for currentSize and totalSize which results in integer division which removes the fractional part, yielding 0. hence the percentage is always 0.
change it to float percentage = (((float)currentSize/totalSize) * 100); and things will be fine
I assume currentSize and totalSize are int.
currentSize = 4079;
totalSize = 500802;
If they are, then currentSize/totalSize is an integer division. The result will have no fractional part (the fractional part is removed, no round up). Therefore the result is 0.
If one of the operand is double, the result of division will have fraction. Therefore, I cast one integer operand to double.
(double) currentSize
After the calculation, if you want the result to store in int, you have to cast (convert double to int; remove fractional part).
int percentage = (int) ((double) currentSize ...
The whole code is:
int currentSize = 3;
int totalSize = 100;
int percentage = (int) ((double) currentSize / totalSize * 100);
System.out.println(percentage);
If currentSize and totalSize are integers, this calculation will do integer division, which will truncate your fraction down to 0. Use doubles.
Change your code to this:
double percentage = ((double)(currentSize/totalSize) * 100);
progdialog.setProgress(percentage);
Hope it will help yout. :)
Because the result of your calculation is a double with value less than 1. You put it in an integer so it truncates everything behind the decimal separator, resulting in zero. Try storing the value in a double instead.
double occupancyRate = 0.0;
int occupiedRoomsTotal = 12;
int totalRooms = 20;
occupancyRate = (((double) occupiedRoomsTotal / totalRooms)) * 100;
DecimalFormat df2 = new DecimalFormat("#.##");
System.out.println("Occupancy Rate = " + df2.format(occupancyRate) + "%");
Java Division of integers yields zero if both numerator and denominator are both integers and the result is less than 1.
Fix:
Make either of the operands to be floating number or double
e.g. int x = 1;
double y = 3.0;
x/y gives 0.333333
where as 1/3 results in 0.
Related
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;
I want to call a function with a double parameter and an int precision.
This function would have to round that number with the precision number as decimals.
Example: function(1.23432, 4) would have to round that number up with 4 decimals (1.2343). Could anyone help me out with this?
BigDecimal is your friend when it comes to rounding numbers. You can specify a MathContext to explicitly set how you want you rounding to work, and then define the precision you want to use. If you still want a double at the end you can call BigDecimal.doubleValue()
Try this code
String result = String.format("%.2f", 10.0 / 3.0);
// result: "3.33"
First, you get 10precision, then you multiply it by your number, round it to an int and divide by 10precision:
public double round(double number, int precision) {
// 10 to the power of "precision"
double n = Math.pow(10.0, precision);
// multiply by "number" and cast to int (round it to nearest integer value)
int aux = (int) (n * number);
// divide it to get the result
return aux / n;
}
Then you call:
double result = round(1.23432, 4);
System.out.println(result); // 1.2343
Try this:
public String round(double value, int factor) {
double newFactor = convertFactor(factor);
//will convert the factor to a number round() can use
String newVal = Double.toString(Math.round(value / newFactor) * newFactor);
//the value gets rounded
return newVal = newVal.substring(0, Math.min(newVal.length(), factor + 2));
//Convert the result to a string and cut it
//important because a too high value of the factor or value would cause inaccuracies.
//factor + 2 because you convert the double into String, and you have to fill 0.0 out
//Math.min() handles an exception when the factor is higher than the string
}
public double convertFactor(double factor) {
double newFactor = 1;
for(int i = 0; i < factor; i++) {
newFactor /= 10;
//devide the newFactor as many times as the value of the factor isnt reached
}
return newFactor;
}
Use convertFactor() to convert your "normal" factor into a factor (called newFactor) the round() method can use.
The round() method calculates the value and convert it into a String which
the max. lengh of the factor.
Too high values of value and factor would cause inaccuracies, and this little inaccuracies get cutted to get rid of them.
Example code (for your example):
System.out.println("newFactor: " + convertFactor(4)); //only for test!
System.out.println("Rounded value: " + round(1.23432, 4));
//newFactor: 1.0E-4
//Rounded value: 1.2343
According to this question, to create a Double number in a given range, you can use:
Random r = new Random();
double randomValue = rangeMin + (rangeMax - rangeMin) * r.nextDouble();
I'm trying to generate a double number in the double domain [Double.MIN_VALUE, Double.MAX_VALUE] using the same code mentioned above:
package test;
import java.util.Random;
public class Main {
public static void main(String[] args) {
double lower = Double.MIN_VALUE;
double upper = Double.MAX_VALUE;
Random rand = new Random();
for (int i = 0; i < 200; i++) {
double a = lower + (upper - lower) * rand.nextDouble();
System.out.println(a);
}
}
}
However, I'm getting just positive numbers even after many iterations:
1.436326007111308E308
2.7068601271148073E307
1.266896721067985E308
8.273233207049513E306
1.3338832492644417E308
8.584898485464862E307
1.260909190772451E308
1.5511066198317899E307
1.2083062753983258E308
2.449979496663398E307
7.333729592027637E307
7.832069948910962E307
8.493365260900201E307
5.158907971928131E307
3.126231202546818E307
1.3576316635349233E308
1.0991793636673692E308
6.991662398870649E307
My question is: How to generate a double number in the double range?
The results are not what you expected, because MIN_VALUE is the smallest possible positive double value. The smallest possible double value is -Double.MAX_VALUE (note the minus sign).
But you can not simply use lower = -Double.MAX_VALUE, because then, the difference will not be representable as a double, and will overflow.
A first idea would be something like
double d = random.nextDouble() * Double.MAX_VALUE;
if (random.nextBoolean()) d = -d;
to cover the full possible range.
EDIT: A (possibly minor) aside: The proposed method should cover the negative double values as well, and should be correct in the sense that each possible value appears either in its positive or in its negative form with equal probability. However, it will not be able to return the value Double.MAX_VALUE (because the value returned by Random#nextDouble() is strictly smaller than 1.0). But based on the implementation of nextDouble, there anyhow may be double values that will never appear in the output.
Double.MIN_VALUE is the smallest positive value that you can represent as a double.
it is not the largest negative number. that would be -Double.MAX_VALUE
As I said in the comment and others have also said, MIN_VALUE is positive. But even if you use -Double.MAX_VALUE, your computation will overflow double precision when computing upper - lower because the result will be two times the maximum double! One way around this is:
val = Random.nextDouble();
return (val < 0.5) ? (-2 * val) * Double.MAX_VALUE : (2 * (val - 0.5)) * Double.MAX_VALUE;
how can i round up a floating point number to the next integer value in Java? Suppose
2.1 -->3
3.001 -->4
4.5 -->5
7.9 -->8
You should look at ceiling rounding up in java's math packages: Math.ceil
EDIT: Added the javadoc for Math.ceil. It may be worth reading all the method in Math.
http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#ceil%28double%29
public static double ceil(double a)
Returns the smallest (closest to negative infinity) double value that
is greater than or equal to the argument and is equal to a
mathematical integer. Special cases:
If the argument value is already equal to a mathematical integer, then the result is the same as the argument.
If the argument is NaN or an infinity or positive zero or negative zero, then the result is the same as the argument.
If the argument value is less than zero but greater than -1.0, then the result is negative zero.
Note that the value of Math.ceil(x) is exactly the value of
-Math.floor(-x).
try this
float a = 4.5f;
int d = (int) Math.ceil(a);
System.out.println(d);
I had the same issue where I was still getting the smaller int value. It was the division, not the Math.ceil. You have to add a (float) cast to the ints. This is how I fixed it:
int totalNumberOfCachedData = 201;
int DataCountMax = 200;
float ceil =(float) totalNumberOfCachedData / (float)DataCountMax;
int roundInt = (int) Math.ceil(ceil);
This will give me 2 for the value of roundInt.
See
float a=10.34f,b=45.678f;
System.out.println((int)Math.ceil(a));
System.out.println((int)Math.ceil(b));
Output
11
46
If it helps someone, here's how I get this working:
int arraySize = 3;
int pageSize = 10;
int pagesQty = (int) Math.ceil(arraySize / (float) pageSize);
System.out.println(pagesQty);
//Displays 1
Divisor must be a float in order to work properly.
I'm using this:
public static int roundDoubleToUpperInt(double d){
return (d%1==0.0f)?(int)d:(int)(d+1);
}
I need to cast a double to an int in Java, but the numerical value must always round down. i.e. 99.99999999 -> 99
Casting to an int implicitly drops any decimal. No need to call Math.floor() (assuming positive numbers)
Simply typecast with (int), e.g.:
System.out.println((int)(99.9999)); // Prints 99
This being said, it does have a different behavior from Math.floor which rounds towards negative infinity (#Chris Wong)
To cast a double to an int and have it be rounded to the nearest integer (i.e. unlike the typical (int)(1.8) and (int)(1.2), which will both "round down" towards 0 and return 1), simply add 0.5 to the double that you will typecast to an int.
For example, if we have
double a = 1.2;
double b = 1.8;
Then the following typecasting expressions for x and y and will return the rounded-down values (x = 1 and y = 1):
int x = (int)(a); // This equals (int)(1.2) --> 1
int y = (int)(b); // This equals (int)(1.8) --> 1
But by adding 0.5 to each, we will obtain the rounded-to-closest-integer result that we may desire in some cases (x = 1 and y = 2):
int x = (int)(a + 0.5); // This equals (int)(1.8) --> 1
int y = (int)(b + 0.5); // This equals (int)(2.3) --> 2
As a small note, this method also allows you to control the threshold at which the double is rounded up or down upon (int) typecasting.
(int)(a + 0.8);
to typecast. This will only round up to (int)a + 1 whenever the decimal values are greater than or equal to 0.2. That is, by adding 0.8 to the double immediately before typecasting, 10.15 and 10.03 will be rounded down to 10 upon (int) typecasting, but 10.23 and 10.7 will be rounded up to 11.
(int)99.99999
It will be 99.
Casting a double to an int does not round, it'll discard the fraction part.
Math.floor(n)
where n is a double. This'll actually return a double, it seems, so make sure that you typecast it after.
This works fine int i = (int) dbl;
new Double(99.9999).intValue()
try with this, This is simple
double x= 20.22889909008;
int a = (int) x;
this will return a=20
or try with this:-
Double x = 20.22889909008;
Integer a = x.intValue();
this will return a=20
or try with this:-
double x= 20.22889909008;
System.out.println("===="+(int)x);
this will return ===20
may be these code will help you.
Try using Math.floor.
In this question:
1.Casting double to integer is very easy task.
2.But it's not rounding double value to the nearest decimal. Therefore casting can be done like this:
double d=99.99999999;
int i=(int)d;
System.out.println(i);
and it will print 99, but rounding hasn't been done.
Thus for rounding we can use,
double d=99.99999999;
System.out.println( Math.round(d));
This will print the output of 100.