0

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.

tshepang
  • 12,111
  • 21
  • 91
  • 136
minisurma
  • 37
  • 2
  • 9

2 Answers2

4

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • If I use Math.round(((e.getX() - Frame.x)/(Screen.myWidth/World.worldWidth))-8) Still if the value of ((e.getX() - Frame.x)/(Screen.myWidth/World.worldWidth))-8 = -5,04814 it gives me -6. Why? Doesen't really seem to help.. That's not the closest integer in my opinion? I make those calculations with my calculator, not sure what the java code tells.. :D – minisurma Jan 12 '14 at 18:27
  • @minisurma: we don't know the types of your variables/methods. If they're all integers, the arithmetic will be done using integer arithmetic too. I would strongly suggest that as a staring point, you simplify the code by breaking it into separate statements. – Jon Skeet Jan 12 '14 at 18:31
  • @minisurma: See my edit for what I mean. – Jon Skeet Jan 12 '14 at 18:42
  • Woah?! It worked with that! :o Nice! I didn't know that it can't do that kind of calculation if I use so many ( -marks :D Thank you anyway :) – minisurma Jan 13 '14 at 16:57
  • @minisurma: It's not a matter of "can't do that kind of calculation" - you can add extra casts to make it work, but it ends up as an unmaintainable mess. Using separate local variables makes the code much easier to work with. – Jon Skeet Jan 13 '14 at 17:05
0

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.

karkum
  • 427
  • 4
  • 16