Если есть задача получить число вида 0b11111 например с 5-ю единицами, т.е. на входе 5, на выходе 0b11111 = 31, это легко сделать формулой (1 << 5) — 1 (или 2^5 — 1). Можно ли придумать похожую простую формулу, если нужно "полосатое" число с чередующимися битами, т.е. на входе число 7, на выходе 0x1010101 = 85. Можно считать, что на входе нечётное число (или чётное если так будет проще).
Здравствуйте, vsb, Вы писали:
vsb>Если есть задача получить число вида 0b11111 например с 5-ю единицами, т.е. на входе 5, на выходе 0b11111 = 31, это легко сделать формулой (1 << 5) — 1 (или 2^5 — 1). Можно ли придумать похожую простую формулу, если нужно "полосатое" число с чередующимися битами,
(1 << (n + 1)) / 3
А если размер числа ограничен чем-то естественным, например длиной регистра, то лучше будет работать банальный подход навроде такого:
Здравствуйте, vsb, Вы писали:
vsb>Если есть задача получить число вида 0b11111 например с 5-ю единицами, т.е. на входе 5, на выходе 0b11111 = 31, это легко сделать формулой (1 << 5) — 1 (или 2^5 — 1). Можно ли придумать похожую простую формулу, если нужно "полосатое" число с чередующимися битами, т.е. на входе число 7, на выходе 0x1010101 = 85. Можно считать, что на входе нечётное число (или чётное если так будет проще).
Здравствуйте, vsb, Вы писали:
vsb>Если есть задача получить число вида 0b11111 например с 5-ю единицами, т.е. на входе 5, на выходе 0b11111 = 31, это легко сделать формулой (1 << 5) — 1 (или 2^5 — 1). Можно ли придумать похожую простую формулу, если нужно "полосатое" число с чередующимися битами, т.е. на входе число 7, на выходе 0x1010101 = 85. Можно считать, что на входе нечётное число (или чётное если так будет проще).
Для "пяти единиц" G(2,5) = 2^5-1
Для "полосок с пятью единицами и четыремя нулями" G(4,5) = (4^5-1)/3 = 1023/3 = 341 = 1010101b
Вообще, эта формула плоха тем, что для больших n выбегает из разрядной сетки. (На два разряда. Формула для сплошных единиц выбегает на 1 разряд, но там мы не делим, а вычитаем в кольце беззнаковых — поэтому нам более пофиг).
В этом случае лучше прибавить старший член суммы отдельно:
G(4,n) = G(4,n-1) + 4^n
Аналогичным путём мы можем получить любой паттерн. Например, чередование одной единицы и z нулей.
a = 2^(z+1)
Или вообще любое повторение n раз m-разрядного паттерна p
p*G(2^m,n)
Например, паттерн 11011 повторить 3 раза:
p = 11011b = 27, a = 2^5 = 32, n = 3
G(a,n) = 32767/31 = 1057
p*G(a,n) = 28539 = 110111101111011b