Самый быстрый способ перекрыть любое десятичное число
У меня есть две переменные:
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 может использовать для большей производительности.