Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a Array that stores my map data and my Tiles are 64X64. Sometimes I need to convert from pixels to units of tiles. So I was doing:

int x
int y

public void myFunction()
{
    getTile((int) Math.floor(x / TILE_SIZE), (int) Math.floor(y / TILE_SIZE)).doOperation();
}

But I discovered by using (I'm using java BTW) System.out.println((int) (1 / 1.5)) that converting to an int automatically rounds down. This means that I can replace the (int) Math.floor with just x / 64.

But if I run this on a different OS do you think it might give a different result? I'm just afraid there might be some case where this would round up and not down. Should I keep doing it the way I was and maybe make a function like convert(int i) to make it easier? Or is it OK to just do x / 64?

share|improve this question
    
Java behaves the same in any platform. It will always round down. –  Zehelvion Oct 6 '12 at 16:13
2  
Casting a float with (int) in java truncates everything after the decimal. It's not actually rounding, it just gets rid of anything but the integer. –  derivative Oct 6 '12 at 17:07
8  
floor and cast-to-int will be different for negative numbers though. i.e. floor(-2.8) = -3.0 vs (int)-2.8 = -2.0. –  5ound Oct 6 '12 at 17:37

3 Answers 3

up vote 2 down vote accepted

Personally, I would write the code just as:

unsigned int x
unsigned int y

public void myFunction()
{
    getTile(x / 64, y / 64).doOperation();
}

since being a tilemap, you can use it (and thus assume) using positive-only values. This does not affect readability because x and y are declared as unsigned int, quite close to the block, and every programmer knows whether the language performs or not an integer division with the / operator when it is applied to two integers (most of them do). In fact, such a geometrical scenario is probably one of the few ones that shows that integer divisions can be useful.

Moreover, thinking about omptimization of such a snippet represents, in my opinion, one of those cases of "unnecessary preventive optimization": you can often assume that such operations will not be a bottleneck of your code, and thus take actions only when profiling shows the opposite. Performance of casting operations can be difficult to evaluate, in general: they largely depend not only on the language, but also on the compiler, which can remove unnecessary casts, or "translate" them in worse/better assembler.

share|improve this answer

I guess it safe to assume it is never negative, given that doing so would be reading outside the confine of the array. If that the case, simply rotate the bits 6 times which gives the same results but is far faster than using the int divide counterpart.

int x
int y

public void myFunction()
{
     getTile(x >> 6, y >> 6).doOperation();
}
share|improve this answer
    
That is true, however, it is situational, it is possible that in the future he may use different numbers for tile sizes. That reminds me he should probably use constants instead of magic numbers for the tile size –  Zehelvion Oct 6 '12 at 19:29
3  
Personally I'd put the whole calculation inside the actual function and call the function getTileUsingWorldUnit(x, y).doOperation(); leaving the worry about the calculation / optimization in one place rather than each function call. –  John Oct 6 '12 at 20:46
    
I agree with this. It is better to keep this abstract. –  Zehelvion Oct 6 '12 at 21:10
    
@John I think I might do that. thanks for the idea. –  Aidan Mueller Oct 7 '12 at 3:52
    
@ArthurWulfWhite Actually I am using constants :) I figured maybe I'd change it. I probably won't though. But if I need to I can. –  Aidan Mueller Oct 7 '12 at 3:54

Using Math.floor should not greatly decrease performance for your game and it makes the code more readable (self commented) and easy to understand.

Java logic will behave the same in any platform, the only difference between platforms is performance.

I think you could use this to define your tile size (to make the code more readable and easier to modify).

public static final int TILE_WIDTH  = 64;
public static final int TILE_HEIGHT = 64;

now

getTile((int) Math.floor(x / TILE_WIDTH),
        (int) Math.floor(y / TILE_HEIGHT)).doOperation();
share|improve this answer
    
So you're saying leave it like it was because it makes it more readable? –  Aidan Mueller Oct 6 '12 at 16:17
    
I think it is a good trade-off if you are not calling this function thousands of time each frame. I automatically knew what would happen when I saw .floor but casting to (int) behaves differently in different languages, for instance c# just rounds the number. –  Zehelvion Oct 6 '12 at 16:19
    
OK thank you :) –  Aidan Mueller Oct 6 '12 at 16:21
    
@ArthurWulfWhite using an (int) cast in C# does not round the number. But using Convert.ToInt32 does round the number. –  Luis Estrada Oct 6 '12 at 17:53
    
@LuisEstrada Thanks for the correction. –  Zehelvion Oct 6 '12 at 18:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.