Где я могу найти немного смещающегося руководства для C? [закрытый]

Вы могли бы сделать это несколько дешевле, просто вставив диапазон после ввода и применив отрицательное поле справа к входу:

<input type='number' style='margin-right: -10em;'><span>days</span>

Таким образом, вы вообще не касаетесь своих данных, и это остается чисто косметическим.

6
задан Community 23 May 2017 в 12:01
поделиться

11 ответов

Разрядное смещение только, что это буквально означает: смещение всех битов в данной левой или правой последовательности.

Все, что необходимо помнить, - то, что каждое десятичное число (как 6, 7, 3, 2) представлено как последовательность битов в памяти компьютера. Таким образом, если Вы находите что-то вроде этого в части кода C:

(7 >> 1)

это означает, что биты в базовом двоичном представлении 7 должны быть смещены прямо 1 положением.

Я думаю объяснение в ссылке, которую Вы цитируете, довольно ясно. Возможно, запись последовательности битов на бумаге самостоятельно и управление ими как в процитированной ссылке могут помочь.

Или возможно у Вас возможно еще нет понимания, как компьютеры работают с числами внутренне. В этом случае, прежде, чем изучить разрядное смещение, необходимо читать об этом.

7
ответ дан 8 December 2019 в 18:43
поделиться

Ваше испытание необходимость в большем количестве инструментов в Вашем инструментарии для ответа на те вопросы, чем смещение.

Я думаю, что необходимо будет запустить очень простой о том, как числа представлены в двоичном файле. Затем Вы захотите думать о том, как установить и очистить определенные биты в том числе или группу битов одновременно. Необходимо будет знать, как протестировать, чтобы видеть, установлена ли определенная группа битов и о маскировании. Необходимо будет смочь сделать все вышеупомянутое с побитовыми операторами and/or/xor/inversion/etc операторы. Затем Вы захотите знать о смещении - движущиеся биты, левые и правые определенным количеством пробелов. Вы захотите знать то, что происходит с битами, оставленными "пустыми". Действительно ли это заполнено 1 или 0? Когда это заполнено 1 или 0?

Поиск с помощью Google "учебного руководства по битовым операциям", кажется, придумал некоторые многообещающие результаты для начала. Но вот некоторые основы для тестирования себя против удостовериться, что Вы понимаете

// 1234 in hex, you understand this is not 1234 in decimal? Do you understand
// how specifying in hex makes it easier to think about the binary representation?
unsigned short i = 0x1234; 
// flip all the bits in 0x1234
printf("%04x", ~i);

// Test - Is the most significant bit set?
// mask is a binary number with the most significant bit set. Do
// you understand why this is so?
unsigned short mask = 0x8000;   
if ((mask & i) == mask)
{
    printf("bit set!");
}
else 
{
    printf("bit cleared!");
}

// set the most significant bit
i = i | mask;
printf("Set the MSB of i, check it out: %i\n", i)

// set the second most significant bit
// Do you see how by shifting mask right one it becomes the next most significant bit?
i = i | (mask >> 1);

Удачи!

4
ответ дан 8 December 2019 в 18:43
поделиться

Руководство, с которым Вы связались, действительно хорошо. Что это, Вы не понимаете о смещении бита?

Я не знаю, каков K&R, таким образом, я не могу помочь Вам там.

Можно ли быть более конкретными с вопросом, и я могу отредактировать, чтобы быть более конкретным относительно ответа.

0
ответ дан 8 December 2019 в 18:43
поделиться

Если Вы имеете деньги (и время), захватываете копию Хакеров Delight. Это - вероятно, лучшее руководство по смещению бита вокруг. Это возьмет Вас посредством простых сдвигов (и другие методы управления) полностью через коды Грея и больше...

0
ответ дан 8 December 2019 в 18:43
поделиться

Давайте пройдем одно осуществление для образца.

Упражнение 2-6: Запишите функцию setbits (x, p, n, y), который возвращает x с n битами, которые начинаются в наборе положения p к самым правым n битам y, оставляя другие биты без изменений.

Давайте сохраним в ind, что младший значащий бит является битом 0 (в положении 0),

Вот псевдокод:

  1. переместите биты p в p+n в x к позиции 0 к n. Это то, где Вы сдвиг вправо.
  2. подготовьте немного маски, которая повернет что-либо из бита n к самому высокому биту в 0s. Можно использовать массив поиска для этого (например, 0xFF для n=8, 0x7F для 7 и так далее), или можно использовать комбинацию бита установки 0 и lef-смещение в цикле.
  3. примените битовую маску к использованию x и. Все биты, о которых мы не заботимся в x, теперь 0
  4. инвертируйте битовую маску. У нас теперь есть набор 1 с на верхнем уровне и набор 0s на нижнем уровне. Биты, которые мы хотим изменить в y, у всех есть 0s в битовой маске.
  5. примените битовую маску к использованию y и. Все биты в y, который мы заменим битами в x, теперь установлены на 0, и биты, которые мы не хотим изменять, неизменны.
  6. установите биты, которые мы хотим изменить в y путем объединения использования X и Y |. Это - критический момент - пробегаются через то, что происходит с пером и бумагой. Биты в x, которые были установлены на 0 в (3), не будут влиять на соответствующие биты в y. Биты в x, которые не были затронуты (3), объединятся с 0s в y (0s из-за step5), устанавливая получающийся бит на значение, которое он имел в x.
0
ответ дан 8 December 2019 в 18:43
поделиться

Запишите биты на бумаге и думайте о стирании их от одного конца и включения больше другого. Мало чем отличаясь от начальной школы и перемещая десятичную точку вокруг при умножении на 10.

Все Ваши функции C собираются переключить нули на нижний регистр.

Так

x = y << 3;

сдвиг средств оставил три бита, и новые биты справа являются всеми нулями, три бита, которые были слева, входят в "битоприемник"

x = z >> 2

потеряйте два бита справа и добавьте два нуля слева.

Что Вы найдете и о чем упражнения K&R, недостающие функции, среди типов процессора там у Вас есть намного больше смещающихся возможностей, чем Вы делаете в C или каком-либо другом высокоуровневом языке.

Вы имеете, поворачивают функции, где бит, отложенный одного конца, переключается другой на нижний регистр,

Таким образом, номер 0xD вращался, 1 бит направо этим способом будет 0xE, потому что lsbit был 1, так сместите 1101 направо, 1 справа становится 1 на левых 1110

Иногда Вы вращаетесь через бит переноса в alu. Позволяет говорят, что перенос укусил, имел нуль в нем, и Вы повернули 0xD один бит 0 1 101 лист 1 0110 0x6. вращайтесь тот еще один 0 1011, и Вы получаете 0xB и так далее.

То, почему Вы когда-либо вращались бы посредством переноса, укусило Вас, спрашивают? Для больших чисел скажите, что Вы имеете регистры на четыре бита и хотите сделать 8 сдвигов разряда, позволяет, говорят, что каждая из букв является битами bcde fghi, где переноса укусил, и другие две группы четыре являются регистрами на четыре бита, запускаются путем вращения левого регистра посредством переноса e abcd fghi, затем поворачивают правильный регистр посредством переноса я abcd efgh, довольно прохладный, мы просто сделали 8 сдвигов разряда с 4 функциями сдвига разряда. если Вы очистились, перенос укусил прежде, чем запуститься (часто существует инструкция для этого, или можно всегда делать что-то, любят, добавляют 0+0, или что-то еще гарантировало, что очистило тот бит), у Вас буду я 0bcd efgh, который мало чем отличается от того, что сделала бы функция сдвига C, если Вы, говорят относительно системы команд на 32 бита, воздействующей на число на 64 бита.

Процессоры часто имеют C как сдвиги, где нуль переключается на нижний регистр, сдвиг abcd уехал, каждый дает сдвиг bcd0 abcd, правильные два дает 00ab.

И это приводит к некоторым проблемам, младшие люди с современными процессорами не думают о таких вещах, потому что целочисленное деление и поддерживается на их процессоре и может работать в единственном такте, назад прежде чем мы имели, делятся или когда деление было десятками к сотням часов, но сдвиг был единственными часами, которые Вы сделаете, все Ваше питание 2 делит или умножает использование, смещающееся вместо этого. возьмите сдвиг номер 0x0D, который уехал два, Вы получаете 0b00001101 <<2 = 0b00110100, или 0x34 0xD является 13 десятичными числами, и 0x34 является 52 десятичными числами. 52 в четыре раза больше чем 13. четыре 2 к питанию 2. смещение на два совпадает с умножением на четыре. Это работает, оба пути, 0x34 смещенные правильные 2 0xD, но здесь проблема, когда Вы входите в отрицательные числа, берете число минус 4 0xFC, теперь делите это на два. Использование C 0xFC>> 1 дало бы 0x7E, но 0x7E является +126 десятичными числами, как делает-4/2 = 126? проблема состоит в том, что C переключает нули на нижний регистр. Вы найдете, что некоторые процессоры имеют арифметический сдвиг, который отличается, чем логический сдвиг, арифметический сдвиг сохраняет верхнее большей частью бита, поэтому если Вы работаете с числом со знаком как 0bQWER, и Вы арифметически сместили тот правильный один бит, Вы получаете 0bQQwe, верхнее большая часть бита оба сдвига в следующий бит, и остается, где это было. сместитесь снова 0bQQQW и так далее. Теперь оставленный арифметический сдвиг переключит на нижний регистр нули а не lsbit, таким образом, 0bQWER смещенный уехал, каждый - 0bWER0. И это имеет смысл, который оставили-4 смещенных, каждый - 0xF8, который является-8,-4 раза два-8 так, чтобы было правильным. Таким образом, Вы найдете, что некоторые процессоры только имеют право арифметического сдвига, но не левое, некоторые позволяют Вам указывать asl, но когда они собирают его, заменяют его lsl (оставленный логический сдвиг) и кто знает, что у некоторых может на самом деле быть отдельный код операции даже при том, что это - та же функция. Я предполагаю, что могут быть некоторые, которые имеют asl и asr и lsr, но никакой lsl.

Просто используйте бумагу и карандаш и поймите вещи, запуститесь с вещественных чисел как примеры, затем пойдите краткий обзор. Хочу вращаться 0x1234 к правильному одному биту, скажем?

0001001000110100  write out the bits 
x0001001000110100 shift right one
0000100100011010  because this is a rotate fill in the new bit with the bit that fell off on the prior operation

хочу теперь сместить два бита направо

0000100100011010 
xx0000100100011010 
1000001001000110

Как был бы я вносить свою лепту вращаться в C?

unsigned int rotate_right_one ( unsigned int x )
{
  unsigned int y;
  y = x & 1;  //save the bit that is about to fall off the right
  x >> = 1;  //logical rotate one bit
  x |= y<<31; //this assumes that unsigned int is 32 bits.
  return(x);
}

Для вращения больше, можно ли просто вызвать эту функцию многократно или думать ли о маске и сместиться ли выше и как это работало бы больше чем на один бит.

Также обратите внимание, что некоторые процессоры только имеют, каждый поворачивает функцию, например, думайте об этом, у меня есть регистр на четыре бита, и я поворачиваю 5 битов, что я получаю?

abcd
bcda  first rotate
cdab  second
dabc  third
abcd  fourth
bcda  fifth

Что сингл поворачивает оставленный, похожи?

abcd
bcda  one bit left.

пять прямо на регистре на четыре бита совпадает с тем, оставленным 5-4=1. Как asl некоторые процессоры позволят Вам кодировать операцию, но ассемблер заменяет ту операцию другим поворачивать nbits-сдвиг использования как поворачивать сумму.

Для некоторых людей логические битовые операции так же жестки как указатели для понимания, но это - фундаментальное и если Вы будете изучать это и будете использовать его, то Вы будете выходом перед своей конкуренцией или теми, которые вокруг Вас.

Вот пример, который считает число битов в некоторой переменной:

for(count=0,r=1;r;r<<=1) if(r&some_variable) count++;

Поймите, что строка кода и Вы хорошо на пути и к изучению C и к логическим битовым операциям.

1
ответ дан 8 December 2019 в 18:43
поделиться

Следует иметь в виду, что почти все те упражнения имеют простое решение, которое может быть записано с интервалом функций IsBitSet (интервал i, интервал n); международный SetBit (интервал i, интервал n); и комбинации <<и>>. Простые решения являются почти всем худшим случаем, но намного легче реализовать и читать. Это отчасти похоже на умножение реализации с точки зрения дополнения или дополнения с точки зрения инкремента.

0
ответ дан 8 December 2019 в 18:43
поделиться

Уже существует большое введение в побитовые операторы прямо здесь на переполнении стека: Здесь

0
ответ дан 8 December 2019 в 18:43
поделиться

Давайте попробуем 2-6, дадим Вам вкус того, как битовые операции работают и затем видят, имеет ли он смысл.

int setbits( int x, int p, int n, int y )
{
    int bitmask = ~0, y_right = 0; 

    /* Ok, first let's get y's rightmost bits.
     * Take our bitmask, shift it left by n bits, leaving the least significant
     * n bits as 0. Then, flip the bitmask so the rightmost n bits become 1, and the
     * leftmost n bits become 0.
     *
     * Then, AND this bitmask with y, to yield y's n rightmost bits.
     */
    bitmask = ~( bitmask << n );
    y_right = bitmask & y;

    /*
     * Ok, now let's use y_right as our bitmask for x.
     * Shift y_right to the left to *begin* at position p.
     */
     y_right <<= p - n;
     x |= y_right;

     return x;
}

Примечание: вышеупомянутое может быть абсолютно неправильным, поскольку я не протестировал его, но оно должно дать Вам достойную идею запуститься с.

0
ответ дан 8 December 2019 в 18:43
поделиться
0
ответ дан 8 December 2019 в 18:43
поделиться

Вот базовое руководство, которое я нашел некоторое время назад на AVRFreaks. Это покажет вам основы, а затем вы сможете перейти к другим руководствам.

0
ответ дан 8 December 2019 в 18:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: