1

Hi I have created this function which be be used to separate a game world into chunks. Each chunk is 32 blocks in size. This formula calculates the start coordinate of a given chunk number of a given world coordinate. It works good but I think it is possible to optimize it but I have no idea. It is important that the formula works with negative numbers.

    static int wrld2chnk(int wrld)
    {
        if (wrld % 32 != 0)
        {
            if (wrld < 0)
                wrld -= (32 + wrld % 32);
            else
                wrld -= wrld % 32;
        }
        return wrld;
    }

// these are example values which can be used to validate the result. The first value in each rpw is the method input, the second is the output:

    (0, 0);
    (31, 0);
    (32, 32);
    (33, 32);
    (-1, -32);
    (-31, -32);
    (-32, -32);
    (-33, -64);
    (-34, -64);
    (-64, -64);
    (-70, -96);
RBarryYoung
  • 55,398
  • 14
  • 96
  • 137
codymanix
  • 28,510
  • 21
  • 92
  • 151

3 Answers3

6

Firstly, the first if can clearly go. The positive case works fine for zero, too:

static int wrld2chnk(int wrld)
{
    if (wrld < 0)
        wrld -= (32 + wrld % 32);
    else
        wrld -= wrld % 32;
    return wrld;
}

But it can be much simpler. You're working around the fact that % cares about the sign. Rounding down to a multiple of a power of two is much easier, just use bitwise AND with the negative of the power of 2 that you're rounding down to:

static int wrld2chnk(int wrld)
{
    return wrld & -32;
}
harold
  • 61,398
  • 6
  • 86
  • 164
0

How about now guys..??

if(wrld>0)
wrld = (wrld/32)*32;
else
wrld = ((wrld/32)-1)*32
Jimmy
  • 203
  • 1
  • 10
  • OP has `wrld -= wrld % 32` for that case. How is this an improvement? – harold Dec 21 '13 at 16:31
  • @DSM it doesn't, it rounds the wrong way for negative numbers, so for example it turns -1 into 0 instead of -32 – harold Dec 21 '13 at 16:37
  • @harold: ah, I see. I was fooled by precedence when I tried it at the Python console. – DSM Dec 21 '13 at 16:40
0

Here's my proposal:

int wrld2chnk (int wrld)
{
  return sgn(wrld)*32*((32*(sgn(wrld)==-1)+abs(wrld))/32);
}

Where sgn(x) is:

#define sgn(x) (((x)>=0)?1:-1)

Although if you are concerned about the ternary operator (I just love it), here you have some alternative implementations for sgn(): Is there a standard sign function (signum, sgn) in C/C++?

Community
  • 1
  • 1
mcleod_ideafix
  • 11,128
  • 2
  • 24
  • 32