Evg
Эксперт CАвтор FAQ
21274 / 8291 / 637
Регистрация: 30.03.2009
Сообщений: 22,654
Записей в блоге: 30
1

Реализация целочисленного беззнакового деления

03.12.2009, 12:38. Показов 4897. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Может у кого есть готовая реализация. По сути дела делается деление столбиков через операции сдвигов и вычитаний. Математика на пальцах понятна, но реализовывать подобные вещи не люблю, а потому для начала решил спросить, вдруг у кого-то уже есть
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.12.2009, 12:38
Ответы с готовыми решениями:

Выполнить операции беззнакового умножения и целочисленного беззнакового деления
Лабораторная работа по Архитектуре ЭВМ №2 Задание 1. Создать 3 переменные (размер 1 байт),...

Для двух целых чисел найти остаток и частное от целочисленного деления, частное от вещественного деления
Уважаемые форумчане помогите пожалуйста с двумя программами. Это вопрос жизни и отчисления, я...

Остаток целочисленного деления X на Y
Помогите ПОЖАЛЙСТА решить задачу новичку в мире LISP. Для каждого из следующих условий...

Проверка целочисленного деления.
Пажалуйста помоги те побыстрей Нужна програма которая рандомна проверяет знания деления Типа...

9
Evg
Эксперт CАвтор FAQ
21274 / 8291 / 637
Регистрация: 30.03.2009
Сообщений: 22,654
Записей в блоге: 30
03.12.2009, 23:53  [ТС] 2
Для истории обратная ссылка https://www.cyberforum.ru/asse... 68754.html
0
64 / 63 / 3
Регистрация: 16.11.2009
Сообщений: 156
04.12.2009, 07:19 3
Dividend - делимое.
Divisor - делитель.
Quotient - частное.
Remainder - остаток.
Pascal
1
2
3
4
5
6
7
8
9
Quotient := Dividend;
Remainder := 0;
for i := 0 to NumberBits do
             Remainder:Quotient := Remainder:Quotient SHL 1
             if Remainder >= Divisor then
                          Remainder := Remainder - Divisor;
                          Quotient := Quotient + 1;
             endif
endfor
1
Evg
Эксперт CАвтор FAQ
21274 / 8291 / 637
Регистрация: 30.03.2009
Сообщений: 22,654
Записей в блоге: 30
04.12.2009, 13:35  [ТС] 4
Что-то тут фигня какая-то. Во 2-й строке в Reminder записываем ноль. В 4-й строке его сдвигаем (в итоге получается ноль). В итоге в 5-й строке условие всеглда ложно
0
64 / 63 / 3
Регистрация: 16.11.2009
Сообщений: 156
04.12.2009, 15:14 5
Remainder:Quotient это одно большое число. Старшая часть числа это остаток, а младшая делимое/частное.

Сначала там будет 0:1011b, потом биты по одному двигаются в остаток -> 1:0110b. Допустим делитель 10b. 1 меньше 10b.
Двигаем следующий бит. 10b:1100b. 10 = 10, вычитаем и устанавливаем младший бит в результате -> 0:1101.
Двигаем следующий бит. -> 1:1010. Остаток снова меньше делителя.
Двигаем еще один бит. 11:0100. Остаток больше делителя. Вычитаем и устанавливаем младший бит частного -> 1:0101. Так как у нас было 4 бита в оригинальном числе, на этом цикл заканчивается.
Частное 101b = 5d, остаток 1. 1011b = 11d делить на 10b = 2d результат 5 и 1 в остатке.
0
Evg
Эксперт CАвтор FAQ
21274 / 8291 / 637
Регистрация: 30.03.2009
Сообщений: 22,654
Записей в блоге: 30
04.12.2009, 17:00  [ТС] 6
Я правильно понимаю, что, например, для 32-битного деления запись "Remainder:Quotient" означает 64-битную величину, в старших 32 битах которого записано Reminder, а в младших 32 битах - Quotient?

Добавлено через 3 минуты
Потому что по началу запись "Remainder:Quotient := Remainder:Quotient SHL 1" я воспринял ак некую компактную форму записи "Remainder := Remainder SHL 1; Quotient := Quotient SHL 1"

Добавлено через 3 минуты
Нашёл какой-то исходник, который делает что-то похожее, только не понял, зачем делается в два цикла

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
void unsigned_divide(unsigned int dividend,
            unsigned int divisor,
            unsigned int &quotient,
            unsigned int &remainder )
{
 unsigned int t, num_bits;
 unsigned int q, bit, d;
 int i;
 
 remainder = 0;
 quotient = 0;
 
 if (divisor == 0)
   return;
 
 if (divisor > dividend) {
   remainder = dividend;
   return;
 }
 
 if (divisor == dividend) {
   quotient = 1;
   return;
 }
 
 num_bits = 32;
 
 while (remainder < divisor) {
   bit = (dividend & 0x80000000) >> 31;
   remainder = (remainder << 1) | bit;
   d = dividend;
   dividend = dividend << 1;
   num_bits--;
 }
 
 
 /* The loop, above, always goes one iteration too far.
    To avoid inserting an "if" statement inside the loop
    the last iteration is simply reversed. */
 
 dividend = d;
 remainder = remainder >> 1;
 num_bits++;
 
 for (i = 0; i < num_bits; i++) {
   bit = (dividend & 0x80000000) >> 31;
   remainder = (remainder << 1) | bit;
   t = remainder - divisor;
   q = !((t & 0x80000000) >> 31);
   dividend = dividend << 1;
   quotient = (quotient << 1) | q;
   if (q) {
      remainder = t;
    }
 }
}  /* unsigned_divide */
 
 
 
#define ABS(x)  ((x) < 0 ? -(x) : (x))
 
 
 
void signed_divide(int dividend,
          int divisor,
          int &quotient,
          int &remainder )
{
 unsigned int dend, dor;
 unsigned int q, r;
 
 dend = ABS(dividend);
 dor  = ABS(divisor);
 unsigned_divide( dend, dor, q, r );
 
 /* the sign of the remainder is the same as the sign of the dividend
    and the quotient is negated if the signs of the operands are
    opposite */
 quotient = q;
 if (dividend < 0) {
   remainder = -r;
   if (divisor > 0)
     quotient = -q;
 }
 else { /* positive dividend */
   remainder = r;
   if (divisor < 0)
     quotient = -q;
 }
 
} /* signed_divide */
0
64 / 63 / 3
Регистрация: 16.11.2009
Сообщений: 156
04.12.2009, 18:35 7
Цитата Сообщение от Evg Посмотреть сообщение
Я правильно понимаю, что, например, для 32-битного деления запись "Remainder:Quotient" означает 64-битную величину, в старших 32 битах которого записано Reminder, а в младших 32 битах - Quotient?
Да, так.

А си я не знаю. Не понимаю некоторые команды, наподобие ">>".
0
Evg
Эксперт CАвтор FAQ
21274 / 8291 / 637
Регистрация: 30.03.2009
Сообщений: 22,654
Записей в блоге: 30
04.12.2009, 19:48  [ТС] 8
В Си ">>" - сдвиг вправо, "<<" - сдвиг влево, "|" - битовое or, "&" - битовое and
0
64 / 63 / 3
Регистрация: 16.11.2009
Сообщений: 156
05.12.2009, 08:18 9
хм... Теперь я понял алгоритм этого си кода. Но не понял, почему два цикла. Есть только предположения...

Может пытаются оптимизировать. Первый цикл быстро крутит до первоого remainder>=dividend без лишних движений. Но второй цикл точно не оптимальный. Кажется, автор не знал, что для делимого и частного можно использовать одно число.
0
Evg
Эксперт CАвтор FAQ
21274 / 8291 / 637
Регистрация: 30.03.2009
Сообщений: 22,654
Записей в блоге: 30
05.12.2009, 13:08  [ТС] 10
Цитата Сообщение от Orwomoi Посмотреть сообщение
Но не понял, почему два цикла. Есть только предположения...
Я тоже не понял, но похоже, что код писался по какую-то конкретную архитектуру и конкретный компилятор, который при таком построении кода лучше организует аппаратную накрутку цикла - во втором цикле условные код есть только в конце и под условием стоит только пересылка, видимо оно лучше в конвейер укладывается
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.12.2009, 13:08
Помогаю со студенческими работами здесь

Остаток от целочисленного деления
Надо найти остаток от деления a на b, но при всех значения a,b возвращает b. Пользуюсь Code::Blocks...

Остаток от целочисленного деления
Вывести на экран числа от 1000 до 9999 такие, что среди цифр нет цифр 5 Не могу додуматься до...

Остаток от целочисленного деления
Всем привет) Только начинаю программировать на С++, поэтому иногда сталкиваюсь с ошибками в коде,...

Определить результат целочисленного деления а на b
Даны целые числа а, b (а &gt; b). Определить: а) результат целочисленного деления а на b , не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru