Получить число вида 0b101010101..
От: vsb Казахстан  
Дата: 19.10.18 14:05
Оценка:
Если есть задача получить число вида 0b11111 например с 5-ю единицами, т.е. на входе 5, на выходе 0b11111 = 31, это легко сделать формулой (1 << 5) — 1 (или 2^5 — 1). Можно ли придумать похожую простую формулу, если нужно "полосатое" число с чередующимися битами, т.е. на входе число 7, на выходе 0x1010101 = 85. Можно считать, что на входе нечётное число (или чётное если так будет проще).
Re: Получить число вида 0b101010101..
От: watchmaker  
Дата: 19.10.18 14:18
Оценка: 12 (1)
Здравствуйте, vsb, Вы писали:

vsb>Если есть задача получить число вида 0b11111 например с 5-ю единицами, т.е. на входе 5, на выходе 0b11111 = 31, это легко сделать формулой (1 << 5) — 1 (или 2^5 — 1). Можно ли придумать похожую простую формулу, если нужно "полосатое" число с чередующимися битами,


(1 << (n + 1)) / 3


А если размер числа ограничен чем-то естественным, например длиной регистра, то лучше будет работать банальный подход навроде такого:
0xAAAAAAAA >> (32 - n)
Re: Получить число вида 0b101010101..
От: kov_serg Россия  
Дата: 19.10.18 20:13
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Если есть задача получить число вида 0b11111 например с 5-ю единицами, т.е. на входе 5, на выходе 0b11111 = 31, это легко сделать формулой (1 << 5) — 1 (или 2^5 — 1). Можно ли придумать похожую простую формулу, если нужно "полосатое" число с чередующимися битами, т.е. на входе число 7, на выходе 0x1010101 = 85. Можно считать, что на входе нечётное число (или чётное если так будет проще).


x=(1<<(2*n+1))/3
n-кол-во единиц
Re: Получить число вида 0b101010101..
От: Кодт Россия  
Дата: 22.10.18 16:19
Оценка: 38 (5)
Здравствуйте, vsb, Вы писали:

vsb>Если есть задача получить число вида 0b11111 например с 5-ю единицами, т.е. на входе 5, на выходе 0b11111 = 31, это легко сделать формулой (1 << 5) — 1 (или 2^5 — 1). Можно ли придумать похожую простую формулу, если нужно "полосатое" число с чередующимися битами, т.е. на входе число 7, на выходе 0x1010101 = 85. Можно считать, что на входе нечётное число (или чётное если так будет проще).


Сумма геометрической прогрессии
G(a,n) = a^0 + a^1 + a^2 + ... + a^(n-1) = (a^n-1)/(a-1)

Для "пяти единиц" 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
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.