Самый быстрый способ перекрыть любое десятичное число

У меня есть две переменные:

var elems;
var limit;

Оба могут быть любым случайным целым числом.

Итак, представьте, что elems = 5 и limit = 3, и что elems / limit дает нам набор ящиков.

Если elems кратен пределу, то мы получим только "полные ящики", в противном случае, if limit < elems мы получим одну дополнительную "неполную коробку". If limit > elemsтогда, конечно, мы получаем только "одну полную коробку".

Например (5 / 3):

total elems: 5
limit: 3
offset:              0      3
box number:         [0]    [1]
elems contained:     3      2

offset = box number * limit

В этом примере смещение блока 3 является "неполным блоком", а смещение блока 0 является полным.

Я хочу найти максимальное смещение, для любого случая, когда вам дают любое количество элементов и любое число для ограничения. Проблема, в ее самой простой форме, состоит в том, чтобы найти самый быстрый метод для суммирования ЛЮБОГО числа, в котором есть ЛЮБОЕ десятичное число в ЛЮБОМ месте, таким образом, чтобы он был адаптирован к задаче поиска максимального смещения.

До сих пор я придумал эти решения:

maxOffset = ((elems / limit - 1 | 0) + Math.ceil((elems % limit) / limit)) * limit; 

maxOffset = Math.abs(Math.ceil((elems / limit) - 1) * limit);

maxOffset = (elems === limit) ? 0 : (1 === limit) ? (elems - 1) : (elems / limit >> 0) * limit;

Однако я ищу более элегантное решение. Я думал, может быть:

maxOffset = ((elems / limit) - 1E-16 | 0) * limit; 

Но я не уверен, что именно произойдет с огромными числами (я предполагаю, что это не получится?), И если 1E-16 - это наименьшее десятичное число, которое может иметь любое число с плавающей точкой.

Это совсем не домашняя работа, я просто программист, и я пытаюсь решить эту проблему для CMS, которую я пишу. Надеюсь, мне было ясно, спасибо.

1 ответ

Решение

Глядя на ваш пример, вы хотите

maxOffset = limit * Math.floor((elems - 1) / limit);

так как это самый большой индекс для первого элемента любого блока. Фо для limit = 3, ты получаешь maxOffset == 0 за elems в {0, 1, 2}, maxOffset == 1 за elems в {3, 4, 5} и т. д. Если ваши целые числа неотрицательны, я мог бы написать это как

maxOffset = limit * (((elems - 1) / limit) | 0);

Урок: вместо того, чтобы вычитать некоторое смещение с плавающей запятой из дроби, вместо этого вычтите целое смещение из числителя, и вы можете полностью остаться в целочисленной арифметике, которую механизм JS может использовать для большей производительности.

Другие вопросы по тегам