
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.30] |
![]() |
|
Страницы: (2) 1 [2] все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
Ты число собираешь побитово. Когда надо добавить ещё один бит - всё что у тебя уже есть сдвигаешь на один разряд влево. При этом добавляется ещё один бит и он равен нулю. Если в массиве у тебя единица - устанавливаешь новый бит в единицу при помощи ИЛИ. Цитата tumanovalex @ ![]() ![]() if(len!=sizeof(number)*8) { number<<=sizeof(number)*8-len; number>>=sizeof(number)*8-len; } Здесь смотрим - если в массиве было такое же количество бит как и в переменной-результате, ничего делать не надо. Код выполняется если в массиве бит меньше чем разрадность переменной-результата (или больше, хотя это не предусмотрено). Лучше заменить на: ![]() ![]() if(len<sizeof(number)*8) { number<<=sizeof(number)*8-len; number>>=sizeof(number)*8-len; } Для простого примера - допустим результат у тебя в char 8 бит, а передали только 3 символа в строке. Допустим передали -1 как "111". Тогда после преобразования ты получишь 00000111 - это 7. Чтобы получить правильный знаковый результат нам надо размножить знаковый бит (старший) в старшие разряды. Самый простой способ - сделать это арифметическим сдвигом (битовый сдвиг для знаковых чисел). Сдвигаем влево на 5 бит, получим 11100000. Теперь сдвигаем вправо на 5 бит - т.е. по сути возвращаем число на место, но при этом арифметический сдвиг новые биты слева заполняет знаковым битом. Получаем 11111111 - т.е. -1 как и хотели. И в моём коде везде long можно заменить на long long или __int64 - тогда можно будет преобразовывать до 64 бит, а так как есть только 32. Если в строке больше символов, то используются только младшие. Т.е. в моём коде результат 32 бита, если передать 64 символа в строке - в результат сконвертируется только 32 младших бита. |
Сообщ.
#17
,
|
|
|
Спасибо большое за подробное объяснение! Вроде бы все понятно, но вот самому до этого додуматься, к сожалению, не удалось. Остался только один вопрос: почему при выводе элементов массива narr выводится мусор - числа более 32767? Я подсчитал - выводится кроме заданных при инициализации чисел еще 11 чисел!
|
Сообщ.
#18
,
|
|
|
Ну это вообще элементарно
![]() Цитата tumanovalex @ ![]() ![]() int narr[] = {-1, 1, -2, 2, -4, 4, -8, 8, -16, 16, -64, 64, -128, 128, -32767, 32767}, i = 0, j = 1, num; // ... while(narr[i]) { // ... } У тебя цикл закончится когда в массиве встретится элемент равный нулю. А он у тебя там есть? Правильно - нету. Поэтому выводиться будут числа за массивом (мусор) пока в памяти не встретится 0. Либо замени условие цикла, к примеру на ![]() ![]() while(i<sizeof(narr)/sizeof(narr[0])) Либо просто добавь в конец массива 0: ![]() ![]() int narr[] = { -1, 1, -2, 2, -4, 4, -8, 8, -16, 16, -64, 64, -128, 128, -32767, 32767, 0 }, i = 0, j = 1, num; |
Сообщ.
#19
,
|
|
|
Спасибо большое! Я думал, что для числовых массивов не нужно ставить завершающий ноль. А если в массив должно входить число 0? Тогда только с помощью while? Век живи, век учись. Неисперпаемый язык С/C++!!!
|
Сообщ.
#20
,
|
|
|
не знаю на сколько это гууд, но можно сделать например так
![]() ![]() int a1[] = {0, 1, 2, 3, 4}; int *a2[] = {&a1[0], &a1[1], &a1[2], &a1[3], NULL}; int i = 0; while(a2[i]) { printf("%d", *(a2[i])); ++i; } |
![]() |
Сообщ.
#21
,
|
|
tumanovalex, причём тут язык? Ты сам написал такую логику - цикл останавливается по достижению нуля. Смени условие выхода, и нуль в конце будет не нужен.
|
Сообщ.
#22
,
|
|
|
Да, похоже с годами я становлюсь только старше. Сам же сделал while(narr[i]), т.е. пока истинно, то выполнять. Еще раз проанализировал код cppasm:
![]() ![]() for(i=0; i<len; i++) { number<<=1; if(sbit[i] == '1') number |= 1; } |
Сообщ.
#23
,
|
|
|
Цитата tumanovalex @ Это азы, известные любому, знакомому с битовой арифметикой. Интересно, это он сам придумал или этот код есть в какой-нибудь книге? |
Сообщ.
#24
,
|
|
|
Понятно, мне нужно побольше читать и практиковаться.
|
Сообщ.
#25
,
|
|
|
Знаковое десятичное в двоичное:
![]() ![]() //-------------------------------- #include <bitset> #include <string> //-------------------------------- string mystring; bitset <32> bs; bs = IntTostdBitSet("-1607"); mystring = bitstring.to_string<char, char_traits<char>, allocator<char> >(); //-------------------------------- bitset<32> IntTostdBitSet(int dnum) { int bitpos = 0, absdnum = abs(dnum); bitset <32> bs, bsone; bsone.set(0); //основной код while(absdnum > 0) { bs[(bitpos++)] = absdnum % 2; absdnum = absdnum/2; } //обратный и дополнительный код if(dnum < 0) { //обратный код bs.flip(); //дополнительный код bs = bs | bsone; } return bs; } |