Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - операции с 12-разрядными числами

Ответить
Настройки темы
C/C++ - операции с 12-разрядными числами

Новый участник


Сообщения: 21
Благодарности: 1

Профиль | Отправить PM | Цитировать


Изменения
Автор: .::.DIMA.::.
Дата: 16-03-2013
Решено

Отправлено: 09:44, 10-03-2009

 

Ветеран


Сообщения: 3806
Благодарности: 824

Профиль | Отправить PM | Цитировать


.::.DIMA.::., ну так двоичный вывод надо самому писать: чтобы число преобразовал в строку символов из нолей и единиц. Разрядность указана для того, чтобы вы в интерфейсе нарисовали эти 12 кнопок, а хранить числа можно и в основных типах.

Отправлено: 12:45, 10-03-2009 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


на этом коде можешь отрепетировать арифметику
Код: Выделить весь код
#include <iostream>
#include <string>
using namespace std;

unsigned from_binary(const string& str)
{
    unsigned result = 0;

    for (unsigned pos=0; pos<str.size(); ++pos)
    {
        result = (result << 1) | (str[pos]=='1');
    }

    return result;
}

void print_binary(unsigned value)
{
//    // вариант 1: со сдвигом

//    for (unsigned bitn=32; --bitn<32; )
//    {
//        static const char bit_values[2] = "-x";
//        cout << bit_values[0x1 & (value >> bitn)];
//    }

//    cout << "\n";

    // вариант 2: перебор битов

    for (unsigned bit1=1<<31; bit1; bit1>>=1)
    {
        cout << (bit1 & value ? 'x' : '-');
    }

    cout << "\n";
}

void main()
{
    // перевели из двоичного (в с++ билдере не работает запись 0b1110101010101)
    unsigned value1 = from_binary("00001010001010010111");
    unsigned value2 = from_binary("00000010010100010001");

    print_binary(value1);
    print_binary(value2);
    print_binary(value1 & value2);
}
Это сообщение посчитали полезным следующие участники:

Отправлено: 19:42, 10-03-2009 | #3


Аватара для Drongo

Будем жить, Маэстро...


Сообщения: 6694
Благодарности: 1393

Профиль | Сайт | Отправить PM | Цитировать


Цитата pva:
Код: Выделить весь код
unsigned value1 = from_binary("00001010001010010111");
unsigned value2 = from_binary("00000010010100010001");
»
Ух ты, класс, интересное решение. А я думал эти числа можно в два массива загнать.

-------
Правильная постановка вопроса свидетельствует о некотором знакомстве с делом.
3нание бывает двух видов. Мы сами знаем предмет — или же знаем, где найти о нём сведения.
[Quick Killer 3.0 Final [OSZone.net]] | [Quick Killer 3.0 Final [SafeZone.cc]] | [Парсер логов Gmer] | [Парсер логов AVZ]

http://tools.oszone.net/Drongo/Userbar/SafeZone_cc.gif


Отправлено: 19:55, 10-03-2009 | #4

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


по сути это и есть два массива типа char[], только вместо 0 и 1 соответсвенно 30 и 31. Даже наверное конструкция типа
Код: Выделить весь код
result = (result << 1) | (0x1 & (str[pos] - '0'));
смотрелась бы лучше в from_binary()

Вот ещё прикольная интерпретация: модель микросхемы.
Код: Выделить весь код
#include <iostream>
using namespace std;


// в чипе стоит цифровой вольтметр :) на основе простейшего ADC

char __amp_boost [4] = {0, 1, 1, 1}; // у транзистора ниже напряжения отпирания.
char __amp_fade  [4] = {0, 0, 1, 1}; // у транзистора выше напряжения отпирания.
char __amp_wave  [4] = {0, 1, 0, 1}; // фиг знает что, наверное нет такого
char __amp_neg   [4] = {1, 0, 0, 0}; // фиг знает что, наверное нет такого
char __amp_off   [4] = {0, 0, 0, 0}; // разрыв цепи

struct micro_op
{
    char op;
    char hotch_c;      // перенос вкл/выкл
    char hotch_bit1;   // операнд 1 вкл/выкл
    char hotch_bit2;   // операнд 2 вкл/выкл
    char* amp_r;       // усилитель для результата
    char* amp_c;       // усилитель для переноса
};

micro_op micro_ops[5] = {
    {'+', 1, 1, 1,  __amp_wave, __amp_fade},
    {'&', 0, 1, 1,  __amp_fade, __amp_off},
    {'|', 0, 1, 1,  __amp_boost,__amp_off},
    {'^', 0, 1, 1,  __amp_wave, __amp_off},
    {'~', 0, 1, 0,  __amp_neg,  __amp_off}};

struct macro_CPU
{
    char _f[12]; // флаги
    char _a[12]; // аккумулятор
    char _b[12]; // регистр 1
    char _c[12]; // регистр 2

    static void output(const char* name, const char* register1);
    void output();
    void operate(char op);
};

void macro_CPU::output(const char* name, const char* register1)
{
    cout << name << " : ";
    for(unsigned n=0; n<12; ++n) cout << register1[n];
    cout << "\n";
}

void macro_CPU::output()
{
    cout << "CPU state:\n";
    output("F", _f);
    output("A", _a);
    output("B", _b);
    output("C", _c);
}

void macro_CPU::operate(char op)
{
    micro_op* op_scheme;

    for ( op_scheme=micro_ops; op_scheme<micro_ops+5 && op_scheme->op!=op; ++op_scheme) {}

    if ( op_scheme < micro_ops+5)
    {
        // установка переноса полезна для многобайтовых операций
        bool c = (_f[11]=='1'); // перенос

        for (unsigned bit_n=12; --bit_n<12; )
        {
            // напряжение поступает на контакты схемы

            bool bit1 = (_b[bit_n]=='1');
            bool bit2 = (_c[bit_n]=='1');

            // получаем напряжение на смесителе
            int voltage = (c & op_scheme->hotch_c) +
                        (bit1 & op_scheme->hotch_bit1) +
                        (bit2 & op_scheme->hotch_bit2);

            // прогоняем через фильтр
            bool result = op_scheme->amp_r[voltage];
            c           = op_scheme->amp_c[voltage];

            // снимаем со схемы
            _a[bit_n] = '0' + result;
        }

        _f[11] = '0' + c; // для многобайтоывых операций
    }
}

void main()
{

    macro_CPU cpu = {
        "000000000000",  // F
        "000000000000",  // A   
        "000011010001",  // B
        "000010101001"}; // C

    cpu.output();
    cpu.operate('+'); // A = B op C
    cpu.output();
}

Последний раз редактировалось pva, 10-03-2009 в 23:00.

Это сообщение посчитали полезным следующие участники:

Отправлено: 20:29, 10-03-2009 | #5

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Цитата .::.DIMA.::.:
В книгах этих примеров, к сожалению, нет »
неправда, в книгах как раз полно, на тему "двоичная арифметика"
http://yandex.ru/yandsearch?rpt=rad&...B8%D0%BA%D0%B0
если нужно просто посчитать и выдать результат, то можно просто произвести указанное действие над числами (сложить там или операцию `&`).
если нужно имитировать действия микропроцессора (то есть показать как меняются биты), то нужно писать имитирующую программу.
Определись, что тебе нужно и почитай книги то

Отправлено: 08:52, 12-03-2009 | #6


Аватара для Alan85

Старожил


Сообщения: 463
Благодарности: 91

Профиль | Отправить PM | Цитировать


для операций AND OR и XOR можно не переводить в тип unsigned short (двойная работа). Я предлагаю вот так:
Код: Выделить весь код
#include <iostream>
#include <string>
using namespace std;
string op_and(string s1, string s2)
{    cout<<s1<<'\n'<<"AND\n"<<s2<<'\n'<<"Equals\n";
	string ret="000000000000";
	for (int i = 0; i <= 11; i++)
	   if (s1[i]=='1'&&s2[i]=='1') ret[i]='1';

	return  ret;
}

string op_or(string s1, string s2)
{
  cout<<s1<<'\n'<<"OR\n"<<s2<<'\n'<<"Equals\n";
	string ret="000000000000";
	for (int i = 0; i <= 11; i++)
	   if (s1[i]=='1'||s2[i]=='1') ret[i]='1';

	return  ret;
}

string op_xor(string s1, string s2)
{
  cout<<s1<<'\n'<<"XOR\n"<<s2<<'\n'<<"Equals\n";
	string ret="111111111111";
	for (int i = 0; i <= 11; i++)
	   if ((s1[i]=='1'&&s2[i]=='1')||(s1[i]=='0'&&s2[i]=='0')) ret[i]='0';

	return  ret;
}
int main(int argc, char* argv[])
{
 string s1="001111100011" ;
 string s2="001010100011" ;
 string s3="";
 s3=op_and(s1,s2);
 cout<<s3<<'\n';
 s3=op_or(s1,s2);
 cout<<s3<<'\n';
  s3=op_xor(s1,s2);
 cout<<s3<<'\n';
 cin>>s3;
	return 0;
}
А для операций ADD и SUB придется переводит в число потом добавлять, вычитать и переводить обратно. В этом помогут исходники pva
Это сообщение посчитали полезным следующие участники:

Отправлено: 18:56, 12-03-2009 | #7

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Alan85, напиши op_plus()
я подскажу:
Код: Выделить весь код
char carry_bit = '0'; // флаг переноса
...
// побитовые операции
char new_carry_bit = (s1[i]=='1' && s2[i]=='1') || (carry_bit=='1' && (s1[i]=='1' || s2[i]=='1')) ? '1' : '0';
ret[i] = (s1[i]=='0' && s2[i]=='0' && carry_bit=='0') || (new_carry_bit=='1'  && (s1[i]=='0' || s2[i]=='0' || carry_bit=='0') || ? '0' : '1';
carry_bit = new_carry_bit;
Мне просто показалось что через применение суммирования будет гораздо проще, потом пришла на ум физическая подоплёка, а потом просто унифицировал алгоритм для всех операций, поэтому он не очень похож на работу с битами

Последний раз редактировалось pva, 12-03-2009 в 21:08.

Это сообщение посчитали полезным следующие участники:

Отправлено: 20:36, 12-03-2009 | #8


Аватара для Alan85

Старожил


Сообщения: 463
Благодарности: 91

Профиль | Отправить PM | Цитировать


ладно... решил уж закончить раз начал:
Код: Выделить весь код
string op_add(string s1, string s2)
{
  cout<<s1<<'\n'<<"ADD\n"<<s2<<'\n'<<"Equals\n";
  string ret="000000000000";
  int a=0;
  int b=0;
  for (int i = 0; i <= 11; i++)
  {
	if (s1[i]=='1')  {a<<=1;a+=1;  }else a<<=1   ; // преобразование строка -> число
	if (s2[i]=='1')  {b<<=1;b+=1;  }else b<<=1   ; // путем смещения разрядов
  }
  a+=b;
  for (int i = 11; i >= 0; i--) if (a%2) {ret[i]='1'; a>>=1;} else a>>=1   ; //преобразование число -> строка тем же макаром (только наоборот)

	return  ret;
}

string op_sub(string s1, string s2)
{
  cout<<s1<<'\n'<<"SUB\n"<<s2<<'\n'<<"Equals\n";
  string ret="000000000000";
  int a=0;
  int b=0;
  for (int i = 0; i <= 11; i++)
  {
	if (s1[i]=='1')  {a<<=1;a+=1;  }else a<<=1   ;
	if (s2[i]=='1')  {b<<=1;b+=1;  }else b<<=1   ;
  }
  a-=b;
  for (int i = 11; i >= 0; i--) if (a%2) {ret[i]='1'; a>>=1;} else a>>=1   ;

	return  ret;
}
Это сообщение посчитали полезным следующие участники:

Отправлено: 21:34, 12-03-2009 | #9

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Цитата Alan85:
Код: Выделить весь код
for (int i = 0; i <= 11; i++)
 {
 if (s1[i]=='1') {a<<=1;a+=1; }else a<<=1 ; // преобразование строка -> число
 if (s2[i]=='1') {b<<=1;b+=1; }else b<<=1 ; // путем смещения разрядов
 }
 a+=b;
 for (int i = 11; i >= 0; i--) if (a%2) {ret[i]='1'; a>>=1;} else a>>=1 ; //преобразование число -> строка тем же макаром (только наоборот)
»
Так не честно, побитно начал - так побитно заканчивай, не надо хитрить ;-)

Отправлено: 13:54, 13-03-2009 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - операции с 12-разрядными числами

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
C/C++ - [решено] операции с матрицами на С+ пчелка Программирование и базы данных 10 22-10-2010 09:48
Получение массива из строки с числами malev AutoIt 3 11-09-2009 00:08
[решено] Bash | Арифметические операции Coutty Программирование в *nix 4 01-06-2009 13:16
Битовые операции farik Программирование и базы данных 1 05-02-2006 17:15
Операции с матрицами Plutonium 239 Хочу все знать 6 30-09-2004 05:00




 
Переход