Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Операция побитового сдвига 
:(
    Опции темы
marina12
Дата 15.2.2013, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 15.2.2013

Репутация: нет
Всего: нет



Задание - написать программу,которая переводила бы число типа unsigned char из десятичной СС в двоичную. Начала писать, используя операцию побитового сдвига, но программа работает неверно, в результате выдаёт неправильное число + в десятичной системе. Подскажите пожалуйста, в чем ошибка!
Код

#include "stdafx.h"
#include <stdio.h>
#include <math.h>


void main()
{
    unsigned char a;
    int i,c;
    printf("vvedite desyatichnoe chislo=");
    scanf("%c",&a);
    for (int i=0;i<8;i++)
    {
        c=a;
        (c<<i)>>7;
        printf("%d",c);
    }


}


PM MAIL   Вверх
Albor
Дата 15.2.2013, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



(c<<i)>>7 не изменяет с, попробуйте внести это выражение в printf вместо c
PM MAIL ICQ   Вверх
marina12
Дата 15.2.2013, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 15.2.2013

Репутация: нет
Всего: нет



Цитата(Albor @ 15.2.2013,  13:42)
(c<<i)>>7 не изменяет с, попробуйте внести это выражение в printf вместо c

Не выходит, всё равно выдает длинное число...
PM MAIL   Вверх
Albor
Дата 15.2.2013, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



 scanf("%c",&a); читает код символа. попробуйте изменить строку с=a, на c=a-'0';
Код

#include <stdio.h>
#include <math.h>
int main()
{
    unsigned char a;
    unsigned char c;
    printf("vvedite desyatichnoe chislo=");
    scanf("%c",&a);
    for (int i=0;i<8;i++)
    {
        c=a-'0';
        printf("%d",((c<<i)>>7)&1);
    }
    return 0;
}


Это сообщение отредактировал(а) Albor - 15.2.2013, 14:24
PM MAIL ICQ   Вверх
IValdemar
Дата 16.2.2013, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 10.1.2012

Репутация: нет
Всего: нет



Цитата(marina12 @  15.2.2013,  12:56 Найти цитируемый пост)
unsigned char a;
    int i,c;
    printf("vvedite desyatichnoe chislo=");
    scanf("%c",&a);

Я не очень понимаю как вы собираетесь десятизначное(!) число записать в один символ smile 

Цитата(marina12 @  15.2.2013,  12:56 Найти цитируемый пост)
Задание - написать программу,которая переводила бы число типа unsigned char из десятичной СС в двоичную

Я так понимаю число должно быть 0..9. Тогда достаточно просто представить его в двоичном виде
Цитата(marina12 @  15.2.2013,  12:56 Найти цитируемый пост)
c=a;

Здесь в "с" запишется номер символа. Надо так с=a-'0'; собственно об этом уже написали выше.
Далее:
Цитата(marina12 @  15.2.2013,  12:56 Найти цитируемый пост)
(c<<i)>>7

Чего вы пытались добиться этой строкой?
Вот так будет правильно:
Код

bool f;

f = (c&(1<<(7-i)));
printf("%d",f);

Чтобы корректно выводилось надо булевую переменную.
Но учтите что так:
Код

 scanf("%c",&a)

Вводится только один символ.

PS И счетчик лучше пустить сверху вниз.
PM MAIL Skype   Вверх
Albor
Дата 17.2.2013, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



Цитата(IValdemar @  15.2.2013,  23:32 Найти цитируемый пост)
Чтобы корректно выводилось надо булевую переменную.

Чтобы корректно выводилось, нужно разобраться как работает конструкция (c<<i)>>7, дизассемблировав код этой конструкции. А получается вот что: число у нас 8-разрядное, а регистры процессора - 32(64), поэтому, сдвинув влево число, его старшие разряды не выпадают, а остаются в регистре, следующий сдвиг вправо на 7 разрядов "подсовывает" ненужные разряды и получается результат отличный от 0 и 1, поэтому ещё нужно фильтровать операцией И. Либо, разделить конструкцию на 2 отдельных:
Код

с=с<<i;
c=c>>7;
  
Здесь, в промежутке между сдвигами, результат записывается из регистра в память, поэтому лишние разряды выпадают и результат будет правильный без "фильтрующей" И
PM MAIL ICQ   Вверх
IValdemar
Дата 18.2.2013, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 10.1.2012

Репутация: нет
Всего: нет



Albor, Это было сказано не касательно выражения (c<<i)>>7, а касательно выражения (c&(1<<(7-i)) или ((c<<i)>>7)&1) результат которых имеет тип bool
PM MAIL Skype   Вверх
winst2014
Дата 19.2.2013, 07:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 19.2.2013

Репутация: нет
Всего: нет



Код

char buffer[x];// где X количество разрядов в числе +1
int binary;
int a=0; 
cin >> a; // вводишь число например 2
itoa(a,binary,2); // конвертируем (входящее значение, выходное значение, система в которую конвертируем)
cout << binary; // вывод на консоль


Это сообщение отредактировал(а) winst2014 - 19.2.2013, 07:49
PM MAIL   Вверх
Albor
Дата 19.2.2013, 09:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



Цитата(IValdemar @  18.2.2013,  17:50 Найти цитируемый пост)
Albor, Это было сказано не касательно выражения (c<<i)>>7, а касательно выражения (c&(1<<(7-i)) или ((c<<i)>>7)&1) результат которых имеет тип bool 

Я не возражаю. ТС теоретически рассчитал правильно, вытолкнув лишние разряды влево/вправо, но допустил несколько ошибок из-за которых результат был не верный. На счёт типа bool у меня возражение, чисто логическое: а почему не char или unsigned char? bool - это true или false, а нам нужны 0 и 1, если false это 0, то true - не 0, т.е. не обязательно 1
Код

if(sizeof(bool)==sizeof(unsigned char))
    {
        unsigned char q=15;
        unsigned char w=9;
        bool bTrue1=1;
        bool bTrue2;
        unsigned char * pw=(unsigned char *)&bTrue2;// это чтобы обмануть компилятор и загнать в  bTrue2 нечто отличное от определённого true как 1
        *pw=q&w; // bTrue2=9 
        if(bTrue1 && bTrue2)// здесь обе переменные не false (более того bTrue2!= true), хотя дебаггер отображает обе переменные как true, они не равны и выражение bTrue1 == bTrue2 вернёт false
        {
            cout<<"Bools equal"<<endl;
        }
    }


Это сообщение отредактировал(а) Albor - 19.2.2013, 11:28
PM MAIL ICQ   Вверх
IValdemar
Дата 19.2.2013, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 10.1.2012

Репутация: нет
Всего: нет



Цитата(Albor @  19.2.2013,  09:22 Найти цитируемый пост)
На счёт типа bool у меня возражение, чисто логическое: а почему не char или unsigned char?

Согласен, я просто перепутал побитовое и логическое "И" smile Результатом побитового является число.

Цитата(IValdemar @  16.2.2013,  00:32 Найти цитируемый пост)
Чтобы корректно выводилось надо булевую переменную.

Для корректного вывода моего примера в printf нужен bool. Так как значением выражения (c&(1<<(7-i)) может быть не 1 или 0, а в выражении  ((c<<i)>>7)&1) будет 1 или 0.  smile 
PM MAIL Skype   Вверх
Albor
Дата 20.2.2013, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



Цитата(IValdemar @  19.2.2013,  22:06 Найти цитируемый пост)
Для корректного вывода моего примера в printf нужен bool. Так как значением выражения (c&(1<<(7-i)) может быть не 1 или 0

Я не уверен на все 100, что это "прокатит" на всех компиляторах. VS генерит код, жестко подставляя 1 вместо true при инициализации переменной или при вычислении выражения, даже если определить true отличным от 1: #define true 255, например (если только не #define true false smile ). В общем, теоретически, ваш код может выдать не совсем то, что ожидается.
PM MAIL ICQ   Вверх
korian
Дата 20.2.2013, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 2
Всего: 17



Цитата(Albor @  20.2.2013,  07:02 Найти цитируемый пост)
Я не уверен на все 100, что это "прокатит" на всех компиляторах. VS генерит код, жестко подставляя 1 вместо true при инициализации переменной или при вычислении выражения, даже если определить true отличным от 1

по стандарту - любое не нулевое число в сравнительных выражения - это истина
true - это всегда единица

Цитата(IValdemar @  15.2.2013,  23:32 Найти цитируемый пост)
bool f;
f = (c&(1<<(7-i)));
printf("%d",f);

И по большому счету в этом коде bool'а тоже нету. (я не уверен, но кажись не гарантируется, что там будет 0 или 1).
f = (c&(1<<(7-i))) != 0; - вот так вот будет bool. (т.е. в f будет 0 или 1 - 100%, по стандарту).
А выводит оно все равно не bool, а int, и разворачивает его до размера инта перед выводом.

Это сообщение отредактировал(а) korian - 20.2.2013, 14:02
PM   Вверх
Albor
Дата 21.2.2013, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: 2
Всего: 9



Цитата(korian @  20.2.2013,  13:01 Найти цитируемый пост)
И по большому счету в этом коде bool'а тоже нету. 

Здесь идёт преобразование к bool.
Вот что говорит стандарт:
Цитата

An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A
zero value, null pointer value, or null member pointer value is converted to false any other value is converted to true.

То есть, результат будет преобразован в true если он не равен 0. Получается что не так уж много криминала в коде 
IValdemar.  С другой стороны, по моему мнению, true - весьма скользкая вещь, например выражение if(val==false) всегда сработает правильно, чего не скажешь о выражении if(val==true).  В дизассемблере видно, что проверка идёт по результату операции только на 0, то есть, закончилась ли операция нулевым результатом и, фактически результат - это бит в флаговом регистре, который м.б. только 0 или 1.

Это сообщение отредактировал(а) Albor - 21.2.2013, 08:39
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1095 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.