У меня есть пара ситуаций, когда мне нужно прижать число с плавающей запятой к верхнему или нижнему концу произвольного диапазона [1]. До сих пор я использовал функции floor
и ceil
с предварительным и последующим масштабированием, а именно:
y*floor(x/y) - x + y
y*ceil(x/y) - x - y
Где y
указывает размер диапазона, к которому мы привязываемся. Это работает, но это выглядит не элегантно, и эти вычисления происходят достаточно часто, чтобы стать узким местом в производительности. Теперь выясняется, что x mod y = x - y*floor(x/y)
, что означает с небольшой алгеброй, что первое выражение может быть упрощено до y - (x mod y)
, то есть только две операции, а не пять, и исключает умножение.
Однако, мне гораздо сложнее понять, как заменить ceil
без использования ветвления (что не принесло бы пользы для производительности). Итак, есть ли способ переписать y*Math.ceil(x/y)
, который дал бы мне возможности для алгебраического упрощения, или я просто застрял с этим?
[1] Если это помогает, y
всегда является целым числом, равным двум, а показатель степени кэшируется и доступен для использования.