Версия для печати темы
Образовательный студенческий форум _ Информатика / Программирование _ Битовые операции
Автор: julia_lisha 5.2.2010, 12:36
Помогите пожалуйста, не понимаю задание....
Заданы два числа <=16.
Найти их произведение и с помощью битовых операций
записать оба множителя и их произведение одно за другим
в ячейку памяти размером в два байта без пропуска битов.
Помогите с алгоритмом....не понимаю с чего необходимо начать....
Спасибо, VIP)
Автор: Евгений М. 5.2.2010, 13:52
Подсказка: Для начала откройте 4 ячейки с памятью. 2 используются как исходные данные, 1 - как результат, 1 - как вспомогательна (хотя без четвертой обойтись и использовать как вспогательную ячейку для второго числа).
Далее вспоминаем четвертый и пятый класс математики, где учили как умножать, и сопоставить это с битовыми операциями умножения.
ЗЫ: Ассемблер в универе пока не изучал. Это то что я вспомнил первой лекции по программированию на C.
Автор: julia_lisha 5.2.2010, 14:59
Цитата
Для начала откройте 4 ячейки с памятью.
Это переменные объявить

или что сделать?)
Автор: julia_lisha 5.2.2010, 16:46
Код
#include "stdafx.h"
#include "iostream"
#include "windows.h"
int my_c(int a,int b)
{
int rez=0;
rez=a*b;
return rez;
}
void main()
{
int a, b;
system("title Вычисление значения выражения");
printf("Vvedite chislo A:\n");
scanf("%d",&a);
printf("Vvedite chislo B:\n");
scanf("%d",&b);
if (a>16 || b>16)
{
printf("Chisla dolgni bit' <=16 \n");
}
else
{
printf("C++=%i\n",my_c(a,b));
}
system("pause");
}
Цитата
сопоставить это с битовыми операциями умножения
что то не понятно....это как сделать?)
еще я уже много прочитала и думаю мне не обходим оператор
sizeof только где не могу понять...
Автор: julia_lisha 5.2.2010, 17:32
С алгоритмической точки зрения понятия “переменная” и “адрес ячейки” памяти являются идентичными Я на правильном пути)
Цитата
1 - как вспомогательна (хотя без четвертой обойтись и использовать как вспогательную ячейку для второго числа).
как то не очень понятно...что храниться то тут будет?)
Автор: Евгений М. 6.2.2010, 5:44
Ой, а я подумал вам нужно написать программу 100% на ассемблере. Поэтому заговорил об открытии ячейкеек памяти.
- Насчет переменной типа int у меня кое-какие опасения. Лично у меня переменная такого типа занимает 4 байта. Лучше использовать переменную типа __int16. Она точно занимает 2 байта.
- В условии сказано, что оба множителя и произведение должны находиться в памяти последовательно. Такое можно реализовать как массив, в котором первые два элемента множители, а третий - произведение.
- Насчет арифметики из младших классов и сопоставление с арифметикой двоичной системы.
Вот пример:
__11
__11
----
__11
_11
----
1001
Я поставил нижние черты для выравнивания символов.
Данный пример - намек на идею алгоритма умножения.
Автор: julia_lisha 6.2.2010, 16:33
Цитата
Такое можно реализовать как массив, в котором первые два элемента множители, а третий - произведение.

это необходимо реализовать массив как Аi*Bi, так?
Цитата
- Насчет арифметики из младших классов и сопоставление с арифметикой двоичной системы.
необходим еще перевод в двоичную систему?
Цитата
Вот пример:
__11
__11
----
__11
_11
----
1001
пример на сложение)
у меня умножение логическое- это AND
00110001
01100111
-----------
00100001так происходит умножение при AND
Автор: Евгений М. 7.2.2010, 10:03
Цитата
это необходимо реализовать массив как Аi*Bi, так?

Не понимаю ваш вопрос. На языке C должно быть так: A[0]-первый множитель, A[1]-второй, A[2]-произведение, т.е. A[2]=A[0]*A[1]
Вообщем намеками и примерами не смог дать понять идею алгоритма...
Ну ладно, придется обьяснить.
Имеем числа A и B представленые в двоичной системе. Представим число B=R3*1000+R2*100+R1*10+R0
где R3,R2,R1,R0 - цифры числа B третьего, второго, первого, нулевого разряда соответственно.
Тогда A*B=A*(R3*1000+R2*100+R1*10+R0)=A*R3*1000+A*R2*100+A*R1*10+A*R0=C3+C2+C1+C0, где Сn=A*Rn*10^n
Теперь разберемся с Rn. Он может быть равен либо 1 либо 0, тогда число Cx=A*10^x либо Cx=0
Умножение на 10^n можно реализовать с помошью команды SHL или ROL (какой из них точно не помню).
Напоминаю, что все представленые выше числа (кроме индексов) записаны в 2-ичной системе счисления.
Вопросы?
Автор: julia_lisha 7.2.2010, 10:51
хм....
вроде как у меня по заданию так:
1. перемножить два числа
2. и с помощью битовых операций собрать результат в 2 байта
с пунком 1 все ясно)
а вот пункт 2 как то не понятно...
Автор: Inspektor 7.2.2010, 11:09
Цитата(julia_lisha @ 7.2.2010, 13:51)

хм....
вроде как у меня по заданию так:
1. перемножить два числа
2. и с помощью битовых операций собрать результат в 2 байта
с пунком 1 все ясно)
а вот пункт 2 как то не понятно...
1) создать массив из двух элементов по 1 байту каждый.
2) запихнуть данные множители в 1 байт:
Код
x=x1<<4+x2;
3) записать то, что мы получили в 2) в перую ячейку массива, а во вторую произведение.
Автор: julia_lisha 7.2.2010, 11:25
Код
MOV ax,[a]
SHL ax,4
OR ax,[b]
MOV byte ptr [rez],al
MOV ax,[a]
IMUL [b]
MOV byte ptr [rez+1],al
ну вот что получилось....как быть дальше?
Автор: julia_lisha 7.2.2010, 13:51
Код
#include "stdafx.h"
#include "iostream"
#include "windows.h"
INT16 my_assembler(INT16 a,INT16 b)
{
INT16 rez=0;
__asm
{
MOV ax,[a]
SHR ax,4
OR ax,[b]
MOV byte ptr [rez],al
MOV ax,[a]
IMUL [b]
MOV byte ptr [rez+1],al
[b]//......
//rez dw ?[/b]
}
return rez;
}
void main()
{
int a, b;
system("title Вычисление значения выражения");
printf("Vvedite chislo A:\n");
scanf("%d",&a);
printf("Vvedite chislo B:\n");
scanf("%d",&b);
if (a>16 || b>16)
{
printf("Chisla dolgni bit' <=16 \n");
}
else
{
printf("Otvet=%i\n",my_assembler(a,b));
}
system("pause");
}
поидеи мне осталось совсем чуть чуть
в выделенном фрагменте чет не понятное....
Автор: Inspektor 7.2.2010, 19:21
Код
INT8 rez[2]={0,0};
__asm
{
mov bx,[a]; //в bx первый аргумент
shl bl,4; //сдвигаем ранее загруженный аргумент влево
mov ax,[b]; //в ax второй аргумент
or bl,al; //в bl помещаются оба аргумента один за другим
mov byte ptr [rez],bl; //запоминаем это чудо
imul [b]; // Умножаем
mov byte ptr [rez+1],al; // сохраняем произведение сразу за множителями
}
return rez[1];
Автор: julia_lisha 8.2.2010, 15:37
большое спасибо java script:emoticon(':blush:', 'smid_9')
можно еще вопросик....
записать оба множителя и их произведение одно за другим
в ячейку памяти размером в два байта без пропуска битов.
знаю что два байта это слово (dw)
и это dw надо как связять как то с результатом....
помогите плиз)
Автор: Inspektor 8.2.2010, 23:17
Цитата(julia_lisha @ 8.2.2010, 18:37)

и это dw надо как связять как то с результатом....
Как это понять? Результат у нас- это два байта в ячейке памяти по адресу rez. Можно вместо массива из двух элементов объявить переменную типа WORD, а для вывода на экран использовать макрос HIBYTE().
Автор: julia_lisha 9.2.2010, 11:11
Цитата(Inspektor @ 8.2.2010, 23:17)

Результат у нас- это два байта в ячейке памяти по адресу rez.
то есть задача решена полностью?)))
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)