Помощь - Поиск - Пользователи - Календарь
Полная версия: Битовые операции > Информатика / Программирование
Образовательный студенческий форум > Другие дисциплины > Информатика / Программирование
julia_lisha
Помогите пожалуйста, не понимаю задание....
Заданы два числа <=16.
Найти их произведение и с помощью битовых операций
записать оба множителя и их произведение одно за другим
в ячейку памяти размером в два байта без пропуска битов.

Помогите с алгоритмом....не понимаю с чего необходимо начать....
Спасибо, VIP)
Евгений М.
Подсказка: Для начала откройте 4 ячейки с памятью. 2 используются как исходные данные, 1 - как результат, 1 - как вспомогательна (хотя без четвертой обойтись и использовать как вспогательную ячейку для второго числа).
Далее вспоминаем четвертый и пятый класс математики, где учили как умножать, и сопоставить это с битовыми операциями умножения.

ЗЫ: Ассемблер в универе пока не изучал. Это то что я вспомнил первой лекции по программированию на C.
julia_lisha
Цитата
Для начала откройте 4 ячейки с памятью.

Это переменные объявить blush.gif или что сделать?)
julia_lisha
Код
#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
С алгоритмической точки зрения понятия “переменная” и “адрес ячейки” памяти являются идентичными Я на правильном пути)

Цитата
1 - как вспомогательна (хотя без четвертой обойтись и использовать как вспогательную ячейку для второго числа).

как то не очень понятно...что храниться то тут будет?)

Евгений М.
Ой, а я подумал вам нужно написать программу 100% на ассемблере. Поэтому заговорил об открытии ячейкеек памяти. blush.gif
- Насчет переменной типа int у меня кое-какие опасения. Лично у меня переменная такого типа занимает 4 байта. Лучше использовать переменную типа __int16. Она точно занимает 2 байта.
- В условии сказано, что оба множителя и произведение должны находиться в памяти последовательно. Такое можно реализовать как массив, в котором первые два элемента множители, а третий - произведение.
- Насчет арифметики из младших классов и сопоставление с арифметикой двоичной системы.
Вот пример:

__11
__11
----
__11
_11
----
1001

Я поставил нижние черты для выравнивания символов.
Данный пример - намек на идею алгоритма умножения.
julia_lisha
Цитата
Такое можно реализовать как массив, в котором первые два элемента множители, а третий - произведение.

blush.gif это необходимо реализовать массив как Аi*Bi, так?

Цитата
- Насчет арифметики из младших классов и сопоставление с арифметикой двоичной системы.

необходим еще перевод в двоичную систему?

Цитата
Вот пример:

__11
__11
----
__11
_11
----
1001

пример на сложение)

у меня умножение логическое- это AND

00110001
01100111
-----------
00100001

так происходит умножение при AND
Евгений М.
Цитата
это необходимо реализовать массив как Аi*Bi, так?

mad.gif Не понимаю ваш вопрос. На языке C должно быть так: A[0]-первый множитель, A[1]-второй, A[2]-произведение, т.е. A[2]=A[0]*A[1]

Вообщем намеками и примерами не смог дать понять идею алгоритма... sad.gif
Ну ладно, придется обьяснить.
Имеем числа 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-ичной системе счисления.
Вопросы? biggrin.gif
julia_lisha
хм....
вроде как у меня по заданию так:
1. перемножить два числа
2. и с помощью битовых операций собрать результат в 2 байта

с пунком 1 все ясно)
а вот пункт 2 как то не понятно...
Inspektor
Цитата(julia_lisha @ 7.2.2010, 13:51) *

хм....
вроде как у меня по заданию так:
1. перемножить два числа
2. и с помощью битовых операций собрать результат в 2 байта

с пунком 1 все ясно)
а вот пункт 2 как то не понятно...

1) создать массив из двух элементов по 1 байту каждый.
2) запихнуть данные множители в 1 байт:
Код
x=x1<<4+x2;

3) записать то, что мы получили в 2) в перую ячейку массива, а во вторую произведение.
julia_lisha
Код
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
Код
#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");
}


поидеи мне осталось совсем чуть чуть smile.gif
в выделенном фрагменте чет не понятное....
Inspektor
Код
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
большое спасибо java script:emoticon(':blush:', 'smid_9')

можно еще вопросик....

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

знаю что два байта это слово (dw)
и это dw надо как связять как то с результатом....
помогите плиз)
Inspektor
Цитата(julia_lisha @ 8.2.2010, 18:37) *
и это dw надо как связять как то с результатом....

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

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


то есть задача решена полностью?)))
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Русская версия Invision Power Board © 2001-2024 Invision Power Services, Inc.