Double to int rounding normal way from .5 [duplicate] - java

This question already has answers here:
Division of integers in Java [duplicate]
(7 answers)
Closed 9 years ago.
I'm making calculation and for that I'm using the following expression:
Player.targetx = (int) (((e.getX() - Frame.x)/(Screen.myWidth/World.worldWidth))-8);
For example:
if the values are (((103 - 40)/(1184/15))-8) the double answer is around -7.20186. Player.targetx still gets value of -8.
Why's that? I would like to make it so that -7.5 gives me answer of -8 and anything like -7,499999 gives answer of -7.

Casting to int always truncates towards 0. To round, you can use Math.round() instead. However, that always rounds halves up:
class Test {
public static void main(String[] args) {
System.out.println(Math.round(-7.7)); // -8
System.out.println(Math.round(-7.5)); // -7
System.out.println(Math.round(-7.2)); // -7
System.out.println(Math.round(+7.2)); // 7
System.out.println(Math.round(+7.5)); // 8
System.out.println(Math.round(+7.7)); // 8
}
}
Are you sure you want to round halves away from zero? If so, Math.round() won't quite do what you want. You could write your own method though:
public static long customRound(double x) {
return x >= 0 ? (long) (x + 0.5)
: (long) (x - 0.5);
}
This will always round away from zero, by either adding or subtracting 0.5 first (depending on the sign) and then truncating towards 0. That produces the same values as before, except that -7.5 is rounded to -8.
EDIT: I suspect the remaining problem is almost certainly due to the division being performed in integer arithmetic. We don't know the types of any of your values, but I suspect they're all int, which would lead to that problem. If you make either of the operands of the division double, it will perform the division in double arithmetic instead. The easiest way to do that - which would also increase readability - is probably to extract some of the expressions to separate variables, and cast where necessary:
double xDifference = e.getX() - Frame.x;
double widthRatio = Screen.myWidth / (double) World.worldWith;
double x = (xDifference / widthRatio) - 8;
Player.targetx = (int) Math.round(x);
If that still doesn't work, at least you'll have a much easier time seeing what's wrong.

The final cast to int causes the result to be rounded. Try changing that cast to double. Or maybe consider using a DecimalFormat for more precise formatting.

Related

Why is my implementation of math.random in my class only returning 0? [duplicate]

This question already has answers here:
math.random, only generating a 0?
(4 answers)
Closed 2 years ago.
I've been trying to create a class to roll dice for games, and my code for one aspect of it is:
public int[] yahtzeeRoll() {
int[] rolls1 = new int[6];
for (int i = 0; i < 6; i++) {
rolls1[i] = ((int) Math.random()*6+1);
}
return rolls1;
}
yet, when I call it in the main method, it only returns 1 for each of the values. Why is this? How can I fix my code so that it generates 6 different numbers when I print the array in the main method?
You are casting the double value returned by Math.random() to int before multiplying by 6, and since Math.random() returns a value < 1, casting it to int results in 0.
Change
rolls1[i] = ((int) Math.random()*6+1);
to
rolls1[i] = (int)(Math.random()*6)+1;
The type casting by appending (type) takes precedence over the * 6 bits afterwards. Therefore, the result from Math.random() is always casted into 0 before you multiply it by 6, which turns out to always be 0 as well.
This answer points to this site which explains it quite well.
Either (int) (Math.random() * 6) + 1 or (int) (Math.random() * 6 + 1) would work as you have intended.
Math.random returns a floating point number between 0 and 1 but you are truncating it down to 0 by using (int) type cast before it. Use parentheses around your expression and then prepend (int) to that if you do wish to use integer truncation.
Btw, I think same sequence should be generated at each run if you don't seed the pseudo-random engine, say with current time or something.
Let's look at the expression.
((int) Math.random()*6+1)
Now Math.random() returns a double that is >=0 and <1.
You then cast that result to an int which means it will always become 0.
If you use.
(int)(Math.random()*6+1)
You are taking the double between 0 and 1, multiplying it by 6 (giving 0 ... 6) adding 1 and then casting to an int. This looks more like what you are looking for.
Math.random() returns double value in range [0, 1) (greater than or equal to 0.0 and less than 1.0). Then you cast that double value to int, so it always results in 0. After that you add 1 to it, so the result always remains 1.
You should cast result of multiplication - Math.random() * 6 instead of casting Math.random() return value:
rolls1[i] = (int)(Math.random()*6)+1;
By the way, you should be aware of operators precedence in Java language. You can have a look here: operator precedence to see nice table that shows that casting has a higher priority than multiplication and addition - this is the reason, why (Math.random()*6) is put in parenthesis for casting (this way you avoid casting only Math.random())
PS. There is also a link to table of operator precedence in official Java tutorial, but it doesn't exactly fit to your problem as it doesn't contain operation of casting - this is the reason, why I provided another link firstly.
You can take a clue from the below output presentation which is self explanatory.
Code:
double random = Math.random();
System.out.println("Math.random()>>"+random);
System.out.println("Math.random()*6>>"+random*6);
System.out.println("(int)(Math.random()*6)>>"+(int)(random*6));
System.out.println("Math.random()*6+1>>"+random*6+1); //+1 here is treated as a string by java and will add at the end of the number
System.out.println("(Math.random()*6+1)>>"+(random*6+1)); //number random*6 will be incremented by 1 as enclosing () will treat them as numbers
System.out.println("(int)(Math.random()*6+1)>>"+(int)(random*6+1));
Output:
Math.random()>>0.6793602796545469
Math.random()*6>>4.076161677927281
(int)(Math.random()*6)>>4
Math.random()*6+1>>4.0761616779272811
(Math.random()*6+1)>>5.076161677927281
(int)(Math.random()*6+1)>>5

Why this equation returns zero even though it should not? [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 9 years ago.
So, I'm doing a fighting game in java and I have this equation that always returns zero.
int x = 90/100*300;
It should be 270 but it returns zero. :|
You're doing integer calculation, so 90/100 results in 0.
If you write it 90.0/100*300, the calculations will be done with doubles (then you'll need to cast it back to int if you want).
The problem here is it first divides 90/100 which is actually 0.9 however since it is an int type the value is 0 and then when you multiply 0 with 300 the output is 0.
90/100 is 0 remainder 90.
You can fix this by re-arranging the values
int x = 90 * 300 / 100; // 270
Do the multiplications before the divisions and as long as you don't get an overflow, this will be more accurate.
Java in this case carries out the multiplication/division in order.
It also interpretes each number as integers.
So, 90/100 = 0.9 and it gets truncated to 0.
and 0 * 300 = 0.
So you end up with 0
You use integer datatype you use float or double datatype and get proper answer of this equation. Integer datatype only decimal value answer return but float and double datatype return answer with floating point then must use float or double datatype in this equation.
I guess you want like this equation, try this
int x = (90/100)*300;

Dividing long by long returns 0 [duplicate]

This question already has answers here:
Is "long x = 1/2" equal to 1 or 0, and why? [duplicate]
(6 answers)
Closed 9 years ago.
I am trying to calculate % of used diskspace in Windows and totaldrive denotes total diskspace of c drive in Long and freedrive dentoes free space in Long.
long totaloccupied = totaldrive - freedrive;
Here calculating % of usage
Long Percentageused =(totaloccupied/totaldrive*100);
System.out.println(Percentageused);
The print statement returns 0. Can someone help as I am not getting the desired value
You are probably dividing a long with a long, which refers to (long/long = long) operation, giving a long result (in your case 0).
You can achieve the same thing by casting either operand of the division to a float type.
Long Percentageused = (long)((float)totaloccupied/totaldrive*100);
You are doing integer division! Since totaloccupied is smaller than totaldrive, the division of both gives the answer 0. You should convert to double first:
double percentageUsed = 100.0 * totalOccupied / totalDrive;
Note that adding the decimal point to the 100 ensures it is treated as a double.
That will be evaluated left to right, the first integer division will return 0 (e.g. 8/10 evaluates to 0). Either convert values to floats or do 100*a/b. Floats will give you a more precise result.

Java percent of number [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
Is there any way to calculate (for example) 50% of 120?
I tried:
int k = (int)(120 / 100)*50;
But it doesn't work.
int k = (int)(120 / 100)*50;
The above does not work because you are performing an
integer division expression (120 / 100) which result is
integer 1, and then multiplying that result to 50, giving
the final result of 50.
If you want to calculate 50% of 120, use:
int k = (int)(120*(50.0f/100.0f));
more generally:
int k = (int)(value*(percentage/100.0f));
int k = (int)(120*50.0/100.0);
Never use floating point primitive types if you want exact numbers and consistent results, instead use BigDecimal.
The problem with your code is that result of (120/100) is 1, since 120/100=1.2 in reality, but as per java, int/int is always an int.
To solve your question for now, cast either value to a float or double and cast result back to int.
I suggest using BigDecimal, rather than float or double. Division by 100 is always exact in BigDecimal, but can cause rounding error in float or double.
That means that, for example, using BigDecimal 50% of x plus 30% of x plus 20% of x will always sum to exactly x.
it is simple as 2 * 2 = 4 :)
int k = (int)(50 * 120) / 100;
Division must be float, not int
(120f * 50 / 100f)
You don't need floating point in this case you can write
int i = 120 * 50 / 100;
or
int i = 120 / 2;

Why does the division of two integers return 0.0 in Java? [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
int totalOptCount = 500;
int totalRespCount=1500;
float percentage =(float)(totalOptCount/totalRespCount);
Why does this always return value 0.0? Also I want to format this into 00.00 format and convert into string?
Because the conversion to float happens after the division has been done. You need:
float percentage = ((float) totalOptCount) / totalRespCount;
You should be able to format using something like:
String str = String.format("%2.02f", percentage);
If you are using int values, using a double may be a better choice and have less rounding error. float can represent int values without error up to ~16 million. double can accurately represent all int values.
double percentage =(double) totalOptCount / totalRespCount;
Percentages are usually multiplied by 100, meaning you can drop the cast.
double percentage = 100.0 * totalOptCount / totalRespCount;
(totalOptCount/totalRespCount)
here both dividend and divisor are of type int which means they will allow only integer values and the answer of such equation will always be an integer literal.
if I break this it will be something like below
(double)(500/1500)
According to the actual calculation, 500/1500 will give you 0.33333 but compiler will convert this into integer literal because both operands are of type int
(double)(0)
Compiler gets an instruction to cast this 0 value to double so you got 0.0 as result
0.0
and then you can change the result to any format as suggeted by #Zach Janicki.
keep in mind if both the operands are of same type than result will be of same type too.
Integer division (which includes long, short, byte, char, int) in Java always returns an int (or long, if one of the parameters is long), rounding towards zero. Your conversion occurs after this calculation.
(The formatting question is already answered by the other answers - alternatively you could also have a look at java.text.NumberFormat, specially java.text.DecimalFormat.)
String.format("%2.02f", (float)totalOptCount/totalRespCount);
to format a double and print out as a percentage, you can use use
System.out.println(new DecimalFormat("##.##").format(yourDouble) + "%"));

Categories

Resources