Алгоритм использует повторное возведение в квадрат (squareToLen
) и умножение (multiplyToLen
). Время выполнения этих операций зависит от размера используемых чисел. Умножения больших чисел в конце расчета намного дороже, чем в начале.
Умножение выполняется только при выполнении этого условия: ((exponent & 1)==1)
. Количество квадратичных операций зависит от количества битов в числе (исключая начальные нули), но умножение требуется только для битов, которые установлены в 1. Проще увидеть операции, которые требуются, глядя на двоичный представление числа:
2000000: 0000111101000010010000000
2500000: 0001001100010010110100000
3000000: 0001011011100011011000000
3500000: 0001101010110011111100000
4000000: 0001111010000100100000000
4500000: 0010001001010101000100000
5000000: 0010011000100101101000000
Обратите внимание, что 2.5M и 4.5M удачны в том, что у них установлено меньше старших бит, чем числа, окружающие их. В следующий раз это произойдет в 8.5M:
8000000: 0011110100001001000000000
8500000: 0100000011011001100100000
9000000: 0100010010101010001000000
Сладкие пятна имеют точную степень 2.
1048575: 0001111111111111111111111 // 16408 ms
1048576: 0010000000000000000000000 // 6209 ms