еще раз о битах
Jan. 14th, 2008 12:44 amВот еще одна задачка для программистов. Если знаете ответ, не пишите. Комментарии скрывать не буду; советую попробовать решить самостоятельно, до того, как подсматривать чужие ответы - красивая штука.
Дано 64-битное число x. Мы делаем с ним следующее (в псевдокоде):
Здесь rot - вращение числа на один разряд влево (выходящий слева бит становится вправо). И accum, и x - 64-битные числа без знака; при сложении мы отбрасываем бит переноса, если он образуется.
Вопросы: 1) что мы получаем? 2) почему это так получается?
Дано 64-битное число x. Мы делаем с ним следующее (в псевдокоде):
accum = 0
do 64 times:
accum += x
x = x rot 1
endЗдесь rot - вращение числа на один разряд влево (выходящий слева бит становится вправо). И accum, и x - 64-битные числа без знака; при сложении мы отбрасываем бит переноса, если он образуется.
Вопросы: 1) что мы получаем? 2) почему это так получается?
no subject
Date: 2008-01-13 10:52 pm (UTC)no subject
Date: 2008-01-13 11:00 pm (UTC)no subject
Date: 2008-01-13 11:03 pm (UTC)no subject
Date: 2008-01-14 09:42 pm (UTC)"кто видел Felix (tm) того ничем уже не удивишь"
наконец-то!
Date: 2008-01-14 12:03 am (UTC)no subject
Date: 2008-01-13 11:04 pm (UTC)2) надо подумать
no subject
Date: 2008-01-13 11:06 pm (UTC)no subject
Date: 2008-01-13 11:25 pm (UTC)1. -к, где к - число зажженых битов в x
2. на каждой из 64 позиций аккумулятора в свое время побывает каждый из битов x, соответственно, результат можно выразить как
- - - - ... -
k k k k ... k - 64 раза.
иными словами,
acc = 2^63*k + 2^62*k + ... + 2^0*k = k(2^63 + ... + 2^0) = k * 111...111 (64 раза) = k * -1 = -k.
no subject
Date: 2008-01-13 11:27 pm (UTC)no subject
Date: 2008-01-13 11:27 pm (UTC)no subject
Date: 2008-01-13 11:32 pm (UTC)no subject
Date: 2008-01-14 06:22 am (UTC)no subject
Date: 2008-01-13 11:25 pm (UTC)соотвественно - (2^64-1)*x = -x
(если ничего не наврал +/-1 - пошел смотреть ответы)
no subject
Date: 2008-01-13 11:26 pm (UTC)no subject
Date: 2008-01-13 11:29 pm (UTC)no subject
Date: 2008-01-13 11:30 pm (UTC)no subject
Date: 2008-01-13 11:29 pm (UTC)Мы складываем само с собой 64 раза число сдвигаемое на 1 бит влево.
Если мы представим это сложением в столбик, то получим такой себе квадрат 64x64.
В каждой строке это число сдвигаемое на бит, но и в каждом столбце оно же!
Следовательно в каждом столбце n-единиц!
Поменяем единицы местами, так, чтобы в каждом столбце они шли подряд.
Так мы получаем n*0xFFFFFFFFFFFFFFFF = -n!
Спасибо за задачку!
Черт! Пока постил опередили...
no subject
Date: 2008-01-13 11:30 pm (UTC)no subject
Date: 2008-01-13 11:32 pm (UTC)Это я, как бы, первый раз поучаствовал в Ваших играх.
Хотя и не самый быстрый способ биты считать :)
no subject
Date: 2008-01-14 10:25 am (UTC)no subject
Date: 2008-01-14 01:58 pm (UTC)no subject
Date: 2008-01-13 11:38 pm (UTC)no subject
Date: 2008-01-13 11:49 pm (UTC)0xff..f напутал.
Красиво, да.
Интересно, это самый эффективный способ посчитать это самое количество? Если пользоваться только базовыми инструкциями процессора.
Хотя, наверно если умело использовать флаг переполнения и условные переходы, то можно быстрее.
no subject
Date: 2008-01-13 11:50 pm (UTC)no subject
Date: 2008-01-14 12:19 am (UTC)no subject
Date: 2008-01-14 12:27 am (UTC)no subject
Date: 2008-01-14 06:25 am (UTC)no subject
Date: 2008-01-14 07:52 am (UTC)Второй алгоритм быстрее, который divite and conquer, основан на следующей мысли: что если бы могли, используя одни и те же инструкции, параллельно вычислить в нижних 32 битах кол-во единиц в них, в верхних - кол-во единиц в них, и тогда остается только сложить? Тот же вопрос для 32 бит решает далее рекурсивно итд.
no subject
Date: 2008-01-14 12:22 am (UTC)no subject
Date: 2008-01-14 12:27 am (UTC)no subject
Date: 2008-01-14 01:07 am (UTC)no subject
Date: 2008-01-14 01:09 am (UTC)no subject
Date: 2008-01-14 01:11 am (UTC)no subject
Date: 2008-01-14 01:39 pm (UTC)no subject
Date: 2008-01-17 07:32 pm (UTC)no subject
Date: 2008-01-14 04:56 pm (UTC)только зачем это, разве быстрее никак нельзя?
кольцевые числа
Date: 2008-01-14 05:30 pm (UTC)no subject
1. Получается минус количество единиц в двоичном представлении x.
2. Представим x как сумму степеней двойки. Для каждой степени двойки аккумулятор будет равен 11111111...1 (т.е. -1). Для всех - -1 умноженное на количество степеней двойки, т.е. минус количество единиц в двоичном представлении x.
no subject
Date: 2008-01-14 08:29 pm (UTC)no subject
Date: 2008-01-16 01:34 am (UTC)no subject
Date: 2008-01-16 03:54 am (UTC)Умножение на отрицательное число и на положительное без знака, ровно с теми же битами - один и тот же результат дает.
no subject
Date: 2008-01-18 08:02 am (UTC)Я тут решил разобраться с логарифмической линейкой. Вооружившись знанием того, что это очень "просто" я приступил к изучению и сразу споткнулся:
Есть способ получить корент из больших чисел(например порядка миллиона), есть даже описание, но описание какое-то не полное. В общем я не понял как оно работает, моет у Вас есть идея?
http://www.sliderule.ca/k12-prep-p14-15.jpg
Буду очень благодарен
no subject
Date: 2008-01-24 09:23 pm (UTC)Каждый ненулевой бит будет повторен 64 раза, вот так:
1111111111111111111111111111111111111111111111111111111111111111
это 2^64-1, что соответствует -1
И эта штука будет прибавлена столько раз, сколько в этом числе ненулевых бит.
В результате accum = -1 * (число ненулевых бит в числе x)
Иначе говоря accum = 2^64 - (сумма цифр x)