Главная » Просмотр файлов » Arndt - Algorithms for Programmers

Arndt - Algorithms for Programmers (523138), страница 27

Файл №523138 Arndt - Algorithms for Programmers (Arndt - Algorithms for Programmers) 27 страницаArndt - Algorithms for Programmers (523138) страница 272013-09-15СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 27)

. . 11 for positive or negative x,respectively (i.e. arithmetical shift is used). With unsigned type the same expression would be 0 or 1according to whether the leftmost bit of x is set.Computing residues modulo a power of two with unsigned types is equivalent to a bit-and using a mask:ulong a = b % 32;// == b & (32-1)All of the above is done by the compiler’s optimization wherever possible.Division by constants can be replaced by multiplications and shift.

The magic machinery inside thecompiler does it for you:5:test.cc@ ulong foo(ulong a)6:test.cc@ {7:test.cc@ulong b = a / 10;290 0000 8B442404movl 4(%esp),%eax291 0004 F7250000mull .LC33// == 0xcccccccd292 000a 89D0movl %edx,%eax293 000c C1E803shrl $3,%eaxSometimes a good reason to have separate code branches with explicit special values. Similar for modulocomputations with a constant modulus:8:test.cc@ ulong foo(ulong a)9:test.cc@ {53 0000 8B4C2404movl 4(%esp),%ecx10:test.cc@ulong b = a % 10000;57 0004 89C8movl %ecx,%eax58 0006 F7250000mull .LC0// == 0xd1b7175959 000c 89D0movl %edx,%eax60 000e C1E80Dshrl $13,%eax61 0011 69C01027imull $10000,%eax,%eax62 0017 29C1subl %eax,%ecx63 0019 89C8movl %ecx,%eaxTo test whether at least one of a and b equals zero use if ( (a+b)==a ) . This works for signedand unsigned integers. Checking whether both are zero can be done via if ( (a|b)==0 ) .

Thisobviously generalizes for several variables as if ( (a|b|c|..|z)==0 ) ). Test whether exactly one oftwo variables is zero using if ( ((a|b)!=0) && ((a+b)==a) ) .In order to toggle an integer x between two values a and b do:1 Soyou can think of it as ‘unsigned arithmetical’ shift.CHAPTER 8. SOME BIT WIZARDRYprecalculate:toggle:157t = a ^ b;x ^= t;// a <--> bthe equivalent trick for floats isprecalculate:toggle:t = a + b;x = t - x;The following functions should be self explaining. In the spirit of the C language there is no check whetherthe indices used are out of bounds.

That is, if any index is greater than BITS_PER_LONG, the result isundefined. Find these in [FXT: file auxbit/bitcopy.h].inline ulong test_bit(ulong a, ulong i)// Return whether bit[i] is set{ulong b = 1UL << i;return (a & b);}inline ulong set_bit(ulong a, ulong i)// Return a with bit[i] set{return (a | (1UL << i));}inline ulong delete_bit(ulong a, ulong i)// Return a with bit[i] set to zero{return (a & ~(1UL << i));}inline ulong change_bit(ulong a, ulong i)// Return a with bit[i] changed{return (a ^ (1UL << i));}inline ulong copy_bit(ulong a, ulong isrc, ulong idst)// copy bit at [isrc] to position [idst]{ulong v = a & (1UL << isrc);ulong b = 1UL << idst;if ( 0==v ) a &= ~b;elsea |= b;return a;}If the functioninline ulong bit_swap_01(ulong a, ulong i, ulong j)// Swap bits i and j of a// Bits must have different values (!)// (i.e.

one is zero, the other one)// i==j is allowed (a is unchanged then){return a ^ ( (1UL<<i) ^ (1UL<<j) );}appears worthless to you then considerinline ulong bit_swap(ulong a, ulong i, ulong j)// Swap bits i and j of a// i==j is allowed (a is unchanged then){#if 1 // optimized:ulong x = (a >> i) ^ (a >> j);// something to do if bit[i]!=bit[j]:CHAPTER 8.

SOME BIT WIZARDRY158if ( 0!=(x&1) ) a = bit_swap_01(a, i, j);return a;#else // non-optimized version:ulong bi = 1UL << i;ulong bj = 1UL << j;ulong m = ~0UL;m ^= bi;m ^= bj; // use xor to make it work for i==julong t = a & m; // delete bits from aif ( a & bi ) t |= bj;if ( a & bj ) t |= bi;return t;#endif}Never ever think that some code is the ‘fastest possible’, there always another trick that can still improveit. Many factors can have an influence on performance like number of CPU registers or cost of branches.Code that performs well on one machine might perform badly on another.

The old trick to swap variableswithout using a temporary//a=0, b=0a=0, b=1a ^= b; //0011b ^= a; //0010a ^= b; //0010equivalent to:tmp = a; a = b; b = tmp;a=1, b=0101101a=1, b=1010111is pretty much out of fashion today. However in some specific context (like extreme register pressure) itmay be the way to go.8.2Operations on low bits/blocks in a wordThe following functions are taken from [FXT: file auxbit/bitlow.h].The underlying idea is that addition/subtraction of 1 always changes a burst of bits at the lower end ofthe word.Isolation of the lowest set bit is achieved viastatic inline ulong lowest_bit(ulong x)// return word where only the lowest set bit in x is set// return 0 if no bit is set{return x & -x; // use: -x == ~x + 1}The lowest zero (or unset bit) of some word x is then trivially isolated using lowest_bit( ~x ). [FXT:lowest zero in auxbit/bitlow.h]Unsetting the lowest set bit in a word can be achieved viastatic inline ulong delete_lowest_bit(ulong x)// return word were the lowest bit set in x is unset// returns 0 for input == 0{return x & (x-1);}while setting the lowest unset bit is done bystatic inline ulong set_lowest_zero(ulong x)// return word were the lowest unset bit in x is set// returns ~0 for input == ~0{return x | (x+1);}CHAPTER 8.

SOME BIT WIZARDRY159Isolate the burst of low bits/zeros as follows:static inline ulong low_bits(ulong x)// return word where all the (low end) ones// are set// e.g. 01011011 --> 00000011// returns 0 if lowest bit is zero://10110110 --> 0{if ( ~0UL==x ) return ~0UL;return (((x+1)^x) >> 1);}andstatic inline ulong low_zeros(ulong x)// return word where all the (low end) zeros// are set// e.g.

01011000 --> 00000111// returns 0 if all bits are set{if ( 0==x ) return ~0UL;return (((x-1)^x) >> 1);}Isolation of the lowest block of ones (which may have zeros to the right of it) can be achieved via:static inline ulong lowest_block(ulong x)//// x= *****011100// l= 00000000100// y= *****100000// x^y = 00000111100// ret = 00000011100//{ulong l = x & -x; // lowest bitulong y = x + l;x ^= y;return x & (x>>1);}Extracting the index of the lowest bit is easy when the corresponding assembler instruction is used:static inline ulong asm_bsf(ulong x)// Bit Scan Forward{asm ("bsfl %0, %0" : "=r" (x) : "0" (x));return x;}The given example uses gcc’s wonderful feature of Assembler Instructions with C Expression Operands,see the corresponding info page.Without the assembler instruction an algorithm that uses proportional log2 (BITS PER LONG) can be used,so the resulting function may look like2static inline ulong lowest_bit_idx(ulong x)// return index of lowest bit set// return 0 if no bit is set{#if defined BITS_USE_ASMreturn asm_bsf(x);#else // BITS_USE_ASM//if ( 1>=x ) return x-1; // 0 if 1, ~0 if 0//if ( 0==x ) return 0;ulong r = 0;2 thanksgo to Nathan Bullock for emailing this improved (wrt.

non-assembler highest bit idx()) version.CHAPTER 8. SOME BIT WIZARDRYx &= -x;BITS_PER_LONG >= 64if ( x & 0xffffffff00000000if ( x & 0xffff0000ffff0000if ( x & 0xff00ff00ff00ff00if ( x & 0xf0f0f0f0f0f0f0f0if ( x & 0xccccccccccccccccif ( x & 0xaaaaaaaaaaaaaaaa#else // BITS_PER_LONG >= 64if ( x & 0xffff0000 ) r +=if ( x & 0xff00ff00 ) r +=if ( x & 0xf0f0f0f0 ) r +=if ( x & 0xcccccccc ) r +=if ( x & 0xaaaaaaaa ) r +=#endif // BITS_PER_LONG >= 64#endif // BITS_USE_ASMreturn r;}#if))))))rrrrrr+=+=+=+=+=+=16032;16;8;4;2;1;16;8;4;2;1;Occasionally one wants to set a rising or falling edge at the position of the lowest bit:static inline ulong lowest_bit_01edge(ulong x)// return word where a all bits from (including) the//lowest set bit to bit 0 are set// return 0 if no bit is set{if ( 0==x ) return 0;return x^(x-1);}static inline ulong lowest_bit_10edge(ulong x)// return word where a all bits from (including) the//lowest set bit to most significant bit are set// return 0 if no bit is set{if ( 0==x ) return 0;x ^= (x-1);// here x == lowest_bit_01edge(x);return ~(x>>1);}8.3Operations on high bits/blocks in a wordThe following functions are taken from [FXT: file auxbit/bithigh.h].For the functions operating on the highest bit there is not a way as trivial as with the equivalent taskwith the lower end of the word.

With a bit-reverse CPU-instruction available life would be significantlyeasier. However, almost no CPU seems to have it.Isolation of the highest set bit is achieved via the bit-scan instruction when it is availablestatic inline ulong asm_bsr(ulong x)// Bit Scan Reverse{asm ("bsrl %0, %0" : "=r" (x) : "0" (x));return x;}else one may usestatic inline ulong highest_bit_01edge(ulong x)// return word where a all bits from (including) the//highest set bit to bit 0 are set// returns 0 if no bit is set{x |= x>>1;x |= x>>2;x |= x>>4;x |= x>>8;CHAPTER 8. SOME BIT WIZARDRY161x |= x>>16;BITS_PER_LONG >= 64x |= x>>32;#endifreturn x;}#ifso the resulting code may look likestatic inline ulong highest_bit(ulong x)// return word where only the highest bit in x is set// return 0 if no bit is set{#if defined BITS_USE_ASMif ( 0==x ) return 0;x = asm_bsr(x);return 1UL<<x;#elsex = highest_bit_01edge(x);return x ^ (x>>1);#endif // BITS_USE_ASM}triviallystatic inline ulong highest_zero(ulong x)// return word where only the highest unset bit in x is set// return 0 if all bits are set{return highest_bit( ~x );}andstatic inline ulong set_highest_zero(ulong x)// return word were the highest unset bit in x is set// returns ~0 for input == ~0{return x | highest_bit( ~x );}Finding the index of the highest set bit uses the equivalent algorithm as with the lowest set bit:static inline ulong highest_bit_idx(ulong// return index of highest bit set// return 0 if no bit is set{#if defined BITS_USE_ASMreturn asm_bsr(x);#else // BITS_USE_ASMif ( 0==x ) return 0;ulong r = 0;#if BITS_PER_LONG >= 64if ( x & (~0UL<<32) ) { x >>= 32; r#endifif ( x & 0xffff0000 ) { x >>= 16; rif ( x & 0x0000ff00 ) { x >>= 8; rif ( x & 0x000000f0 ) { x >>= 4; rif ( x & 0x0000000c ) { x >>= 2; rif ( x & 0x00000002 ) {rreturn r;#endif // BITS_USE_ASM}x)+= 32; }+= 16; }+= 8; }+= 4; }+= 2; }+= 1; }Isolation of the high zeros goes likestatic inline ulong high_zeros(ulong x)// return word where all the (high end) zeros are set// e.g.

11001000 --> 00000111// returns 0 if all bits are set{CHAPTER 8. SOME BIT WIZARDRYx |= x>>1;x |= x>>2;x |= x>>4;x |= x>>8;x |= x>>16;#if BITS_PER_LONG >= 64x |= x>>32;#endifreturn ~x;}The high bits could be isolated using arithmetical right shiftstatic inline ulong high_bits(ulong x)// return word where all the (high end) ones are set// e.g.

11001011 --> 11000000// returns 0 if highest bit is zero://01110110 --> 0{long y = (long)x;y &= y>>1;y &= y>>2;y &= y>>4;y &= y>>8;y &= y>>16;#if BITS_PER_LONG >= 64y &= y>>32;#endifreturn (ulong)y;}However, arithmetical shifts may not be cheap, so we better usestatic inline ulong high_bits(ulong x){return high_zeros( ~x );}Demonstration of selected functions with two different input words:---------------------------------------------------------................1111....1111.111 = 0xf0f7 == word................1...............

Характеристики

Тип файла
PDF-файл
Размер
1,52 Mb
Тип материала
Учебное заведение
Неизвестно

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6354
Авторов
на СтудИзбе
312
Средний доход
с одного платного файла
Обучение Подробнее