Как в одну строчку на Perl определить, что число $n степень двойки?
#260797 from E545D6FE, 6 months ago
Replies (16)
- @teferi:например так — $pow = sprintf ("%#b", $num) =~ '^0b10+$';#260797/1 from Home, 6 months ago
Если степень 2ки — получим в $pow получим единичку =) - @dzhariy:@teferi При $num = 1; возвращает "false" а ведь 1 — это тоже степень двойки :)#260797/2 from E545D6FE, 6 months ago
- @teferi:@dzhariy да, да. чуть поспешил. но это легко исправить заменив + на *#260797/3 from Home, 6 months ago
- @teferi:@teferi можно еще вот так — $pow = ((sprintf ("%#b", $num) =~ '^0b10*$') or ($num == 0));#260797/4 from Home, 6 months ago
А вот если считать что 1/4 например тоже степень двойки, то надо подумать. =) - @dzhariy:@teferi вот только что хотел сказать про отрицательные степени :) А так, решение хорошее :)#260797/5 from E545D6FE, 6 months ago
- @dzhariy:@teferi пожалуй не стоит заморачиватся с отрицательными степенями :) Все равно мало где используется. Решение хорошее и очень даже "Перловое" :) Суровые Сишники решили бы эту проблему через бинарные операции ;)#260797/6 from E545D6FE, 6 months ago
- @teferi:@dzhariy я вот на самом деле сейчас силюсь придумать нормальное решение с бинарными операциями. там кстати с нолем не нужно сравнивать — можно в регулярке перед единицей ? поставить. тоесть (sprintf ("%b", $num) =~ '^1?0*$');#260797/7 from Home, 6 months ago
- @dzhariy:@teferi — тест пройден, это решение еще более совершенно :)#260797/8 from E545D6FE, 6 months ago
- @teferi:@teferi достаточно вроде $num = $num>>1 while not $num%2; Если в нум осталась единица — то степень 2ки. в любом случае такая штука конечно работать дюже быстрее будет чем любая регулярка, тольк с 0 надо придумать что-то.#260797/9 from Home, 6 months ago
- @dzhariy:@teferi А-а-а-а забыл сказать почти самое главное, сорри. Циклы использовать нельзя#260797/10 from E545D6FE, 6 months ago
- @dzhariy:@teferi в том числе goto и оператор "x" ;)#260797/11 from E545D6FE, 6 months ago
- @teferi:@dzhariy хых ну с этого начинать надо было =))))#260797/12 from Home, 6 months ago
- @dzhariy:@teferi да, правильно поставленая задача — это 90% решения :)#260797/13 from E545D6FE, 6 months ago
- @dzhariy:Benchmark: timing 10000000 iterations of Binary, Regex1, Regex2...#260797/14 from E545D6FE, 6 months ago
Binary: 5 wallclock secs ( 3.73 usr + 0.00 sys = 3.73 CPU) @ 2678093.20/s
(n=10000000)
Regex1: 10 wallclock secs ( 9.17 usr + 0.00 sys = 9.17 CPU) @ 1090274.75/s
(n=10000000)
Regex2: 9 wallclock secs ( 8.12 usr + 0.00 sys = 8.12 CPU) @ 1230920.73/s
(n=10000000)
code:
use Benchmark qw(:all);
$num = 2;
$count = 10000000;
timethese($count, {
'Binary' => sub { $pow = "some secret ;)"; },
'Regex1' => sub { $pow = ((sprintf ("%#b", $num) =~ '^0b10*$') or ($num == 0)); },
'Regex2' => sub { $pow = sprintf ("%b", $num) =~ ^1?0*$; },
}); - @teferi:@dzhariy !(x&(x-1)); конечно же! даже странно что вчера так долго думал как его парвильно завернуть.#260797/15 from Home, 6 months ago
- @dzhariy:@teferi Эмм... да. Правильно ;)#260797/16 from CB97B6B4, 6 months ago
