2013-12-25 3 views
1

Рассмотрим две системы координат: одну для самих объектов, одну для кусков, в которой находятся объекты. Рассмотрим размер блока 4, что означает, что объект с координатой 0 находится в куске 0, объект в координате 3 также находится в куске 0, но объект в координате 8 находится в блоке 2, объект в координате -4 находится в куске -1.Chunking Arithmetics

Расчет количества куска для объекта с положительной позицией легко: object.number/chunk_size

Но я не нашел формуляр, который вычисляет правильное положение куска для объектов при отрицательных позициях:

-4/4 = -1 является правильным, но -2/4 = 0 не требуемый результат, хотя -4/4 -1 = -2 теперь неверно, но -2/4 -1 = -1 теперь правильно ...

есть сладкий, короткий способ вычислить каждую позицию, или же мне нужно проверить 2 условия:

chunkx = objectx > 0 ? 
    objectx/chunksize : 
    objectx % chunksize == 0 ? 
     objectx/chunksize : 
     objectx/chunksize - 1; 

Альтернатива:

chunkx = objectx > 0 || objectx % chunksize == 0 ? 
    objectx/chunksize : 
    objectx/chunksize -1; 

На стороне записки: вычисления положения объекта в пределах фрагмента является:

internalx = objectx - chunkx * chunksize 

для как положительные, так и отрицательные (-4 -> 0 ; -2 -> 2; 1 -> 1; 4 -> 0)

Есть ли более элегантный способ рассчитать это, что я наглядно наблюдаю здесь?

ответ

1

Если вы можете позволить себе конвертировать свои номера в плавающие точки и иметь дешевую функцию пола, вы можете использовать пол (-1.0/4.0), чтобы получить -1, как вы пожелаете, но преобразование в плавающую точку может быть дороже, чем филиал.

Другим вариантом является работа с положительными номерами, только добавив к координате объекта достаточно большое число (кратное размеру блока) и вычитая это число, разделенное на размер куска из вашей координаты куска. Это может быть дешевле, чем филиал.

Для вашего второго вопроса, если ваш размер порции случается быть степенью 2, как в вашем примере вы можете использовать двоичную и (-1 & (chunksize-1) == 3)

0

Если ваш размер порции является степенью двойки вы можете сделать:

chunkx = (objectx & ~(chunksize - 1))/chunksize; 

Если размер блока также является постоянным компилятор, вероятно, может превратить это в тривиальный и и сдвиг. НАПРИМЕР,

chunkx = (objectx & 3) >> 2; 

В общем случае, я не думаю, что вы можете устранить ветвь, но вы можете устранить медленную операцию по модулю смещая число перед делением:

chunkx = ((objectx >= 0) ? (objectx) : (objectx - (chunksize - 1)))/chunksize;