![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() ![]() |
![]() |
olven |
![]()
Сообщение
#1
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
Программа умножает двоичные числа в дополнительном коде. Но умножает неправильно. Помогите пожалуйста найти проблему
var |
Федосеев Павел |
![]()
Сообщение
#2
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 298 Пол: Мужской Реальное имя: Федосеев Павел Репутация: ![]() ![]() ![]() |
происходит переполнение разрядной сетки переменной n.
Если ограничить множители 8-ю битами, т.е. диапазоном (-128...+127), то While k<=64 do begin <---- k<8 В дополнительный код неправильно переводит отрицательные числа. Опять же, если ограничиться 8-ю битами, то число (-210)=-102=1111 11102. Алгоритм такой: все 8 бит исходного числа инвертируешь и прибавляешь 1. (-210)=-102=1111 11012 доп+1=1111 11102 доп При умножении двух чисел нужно умножать их модули, а потом с учётом знака результата переводить или не переводить в дополнительный код. Если не сложно, немного реструктурируй код: ввод строки, преобразования в двоичный, в дополнительный коды вынеси в процедуры или функции. А ещё, приведи исходную постановку задачи. Сообщение отредактировано: Федосеев Павел - 24.03.2012 17:06 |
olven |
![]()
Сообщение
#3
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
происходит переполнение разрядной сетки переменной n. Если ограничить множители 8-ю битами, т.е. диапазоном (-128...+127), то While k<=64 do begin <---- k<8 В дополнительный код неправильно переводит отрицательные числа. Опять же, если ограничиться 8-ю битами, то число (-210)=-102=1111 11102. Алгоритм такой: все 8 бит исходного числа инвертируешь и прибавляешь 1. (-210)=-102=1111 11012 доп+1=1111 11102 доп При умножении двух чисел нужно умножать их модули, а потом с учётом знака результата переводить или не переводить в дополнительный код. Если не сложно, немного реструктурируй код: ввод строки, преобразования в двоичный, в дополнительный коды вынеси в процедуры или функции. спасибо большое. поняла. правда 8 бит это немало? мне нужно переводить именно длинные числа... попробовала для длинных не совсем то что нужно выдает... |
Krjuger |
![]()
Сообщение
#4
|
Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 652 Пол: Мужской Реальное имя: Алексей Репутация: ![]() ![]() ![]() |
Привидите пример и резальтат.
|
Федосеев Павел |
![]()
Сообщение
#5
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 298 Пол: Мужской Реальное имя: Федосеев Павел Репутация: ![]() ![]() ![]() |
Можно взять и больше, но дополнительный код для отрицательных чисел будет длиннее. Так для 16 разрядов -210=1111 1111 1111 11102 доп.
для длинных чисел применяют другой тип хранения чисел - массив или строку. И соответственно определяют в виде процедур все операции над числами (+, -, *, /). Имея простые операции уже и реализуют все остальные вычисления. На форуме должны быть примеры. Приведи исходный текст задания. |
olven |
![]()
Сообщение
#6
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
Привидите пример и резальтат. любые числа. диапозон дб Longint -2147483648..2147483647 . 25 и 26 вводимые. результат в двоичн. дополнит. 10010001010 Добавлено через 5 мин. пользователь должен ввести любое десятичное число. программа перевести его в дополнительный код и перемножить. независимо отрицателньое оно или положительное. результат выдается в десятичном же числе. Умножаются длинные целые числа Сообщение отредактировано: olven - 24.03.2012 18:08 |
Федосеев Павел |
![]()
Сообщение
#7
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 298 Пол: Мужской Реальное имя: Федосеев Павел Репутация: ![]() ![]() ![]() |
Я не могу понять смысл задания.
Вот описание работы с длинными положительными целыми числами. Добавим к тем реализациям дополнительное поле "знак" и сможем работать и с отрицательными. Но как к ним прикрутить дополнительный код? |
olven |
![]()
Сообщение
#8
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
Я не могу понять смысл задания. Вот описание работы с длинными положительными целыми числами. Добавим к тем реализациям дополнительное поле "знак" и сможем работать и с отрицательными. Но как к ним прикрутить дополнительный код? смотрела эту тему.. всё что поняла из кода это то что они там кажется столбиком перемножают... мне необходдимо по алгоритму. сложил - сдвинул, сложил-сдвинул.. как я и пыталась |
Федосеев Павел |
![]()
Сообщение
#9
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 298 Пол: Мужской Реальное имя: Федосеев Павел Репутация: ![]() ![]() ![]() |
Я не могу понять смысл задания.
Как прикрутить дополнительный код? ------------------------------------------------------------------------ Может быть речь идёт о типе LongInt? Т.е. всё - и мнгожители и произведение умещается в тип LongInt? Тогда решение задания получается таким: 1. Ввод 1-го числа в виде строки s1. Далее просто преобразование строки в число LongInt (забываем про встроенные возможности языка). 2. Преобразование s1 в беззнаковое (пока) число c1 (типа LongInt) и знак sign1 (boolean) 3. Если c1 должно быть отрицательным, то c1:=(NOT c1)+1. Вернее здесь будет чуть иначе, но это детали. Тоже самое и со вторым числом. Потом умножаем c1 на c2 и выводим результат средствами языка (writeln). Кажется, что я подменяю условие... |
olven |
![]()
Сообщение
#10
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
Я не могу понять смысл задания. Как прикрутить дополнительный код? ------------------------------------------------------------------------ Может быть речь идёт о типе LongInt? Т.е. всё - и мнгожители и произведение умещается в тип LongInt? Тогда решение задания получается таким: 1. Ввод 1-го числа в виде строки s1. Далее просто преобразование строки в число LongInt (забываем про встроенные возможности языка). 2. Преобразование s1 в беззнаковое (пока) число c1 (типа LongInt) и знак sign1 (boolean) 3. Если c1 должно быть отрицательным, то c1:=(NOT c1)+1. Вернее здесь будет чуть иначе, но это детали. Тоже самое и со вторым числом. Потом умножаем c1 на c2 и выводим результат средствами языка (writeln). Кажется, что я подменяю условие... там нет ограничений каким способом. главное чтобы выполнялись условия, то что ты написал это просто мой метод я пыталась решить это так, но для длинных чисел он не работает, из твоих слов поняла, что нужно писать по другому, представлять формат в виде строк или массива. но как это делают я без понятия. пытаюсь разобраться |
Федосеев Павел |
![]()
Сообщение
#11
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 298 Пол: Мужской Реальное имя: Федосеев Павел Репутация: ![]() ![]() ![]() |
Ага, значит в оригинальном условии задачи фраза "дополнительный код" не упоминалась?
|
olven |
![]()
Сообщение
#12
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
Ага, значит в оригинальном условии задачи фраза "дополнительный код" не упоминалась? упоминалась,иначе я б не стала столько мучиться.... я думаю может нужно просто если положит числа то в двоичном прямом коде перемножить. а если отриц то перевести в дополнительный и там попробовать? |
olven |
![]()
Сообщение
#13
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
Длинная арифметика
попробовала умножение описанноездесь. оно тоэе не работает для длинных... ии я что то не понимаю? почему при числах больше 10 переводя в двоичный код результат выдается неверный? |
Федосеев Павел |
![]()
Сообщение
#14
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 298 Пол: Мужской Реальное имя: Федосеев Павел Репутация: ![]() ![]() ![]() |
Приведи пример, на котором возникла ошибка (и данные и программу). Сейчас я попробовал умножение из модуля dlinna - показал верный результат. Никаких дополнительных преобразований в двоичный код там не предполагается. В модуле есть штатные средства визуализации - WriteLong.
Ты уже столько сил затратила на изучение различныных форматов данных... Может стоит уточнить у преподавателя, что требуется от учебной программы? Цитата любые числа. диапозон дб Longint -2147483648..2147483647 . 25 и 26 вводимые. результат в двоичн. дополнит. 10010001010 Добавлено через 5 мин. пользователь должен ввести любое десятичное число. программа перевести его в дополнительный код и перемножить. независимо отрицателньое оно или положительное. результат выдается в десятичном же числе. Умножаются длинные целые числа Если взять это за основу, то получается, что требуется "забыть" о существовании штатных Write и Read, и самостоятельно пересоздать их. Затем "забыть" о существовании типа longint и создать свои процедуры для работы с ним. Вот без реализации умножения и деления (по-сути с чего начался топик): TYPE ----------------------------- Добавлю во вложении исправленный вариант. В нём реализовано сложение, вычитание и умножение. Если реализовать деление, то можно корректно оформить и вывод в десятичном виде. Тогда размер длинных чисел можно будет не ограничивать 4 байтами. ![]() Сообщение отредактировано: Федосеев Павел - 31.03.2012 22:54 |
olven |
![]()
Сообщение
#15
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
спасибо большое, попробую разобраться.... по моему я уже сама запуталась...
|
olven |
![]()
Сообщение
#16
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
скажите пожалуйста можно ли добавить в программу часть которая показывает это умножение?
|
Федосеев Павел |
![]()
Сообщение
#17
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 298 Пол: Мужской Реальное имя: Федосеев Павел Репутация: ![]() ![]() ![]() |
А что нужно показать? В процедуре LongBin_Mul простое умножение в столбик (правда, желательно ввести проверку на переполнение разрядной сетки - но ведь это всего лишь пример). Далее в программе приводится пример использования этой процедуры "LongBin_Mul(c1, c2, c3);", где c1, c2 - первый и второй множители, а c3 - их произведение.
|
olven |
![]()
Сообщение
#18
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
А что нужно показать? В процедуре LongBin_Mul простое умножение в столбик (правда, желательно ввести проверку на переполнение разрядной сетки - но ведь это всего лишь пример). Далее в программе приводится пример использования этой процедуры "LongBin_Mul(c1, c2, c3);", где c1, c2 - первый и второй множители, а c3 - их произведение. как они перемножаются пошагово,показать как осуществляется умножение в дополнительном коде,допустим человеку который не умеет этого делать, как то так сказали. можно еще вопрос о функции hi() и lo() как они выделяют байты? Сообщение отредактировано: olven - 24.04.2012 12:17 |
Федосеев Павел |
![]()
Сообщение
#19
|
Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 298 Пол: Мужской Реальное имя: Федосеев Павел Репутация: ![]() ![]() ![]() |
1) hi/lo
- hi - возвращает старший байт слова (для типа word) или старшее слово (для типа longint). В контексте данной процедуры - старший байт слова (word). - lo - аналогично hi, только возвращает младшую часть. В нашем случае младший байт слова. 2) В процедуре умножения в дополнительном коде как такового нет. В самом начале процедуры выясняются знаки множителей (Sign1 и Sign2) и вычисляется знак результата (SignRes). Далее берётся модуль каждого множителя (LongBin_Abs) и перемножаются именно модули (положительные числа). После перемножения, если нужно (SignRes == TRUE) результат делается отрицательным - переводится в дополнительный код. В принципе, при умножении в столбик мы тоже так и поступаем - умножаем модули чисел и определяем знак результата. 3) Если будет достаточно показать входные числа, затем их абсолютные значения, абсолютное, а затем и знаковое значение произведения, то см. в аттаче. Если требуется показать всё умножение столбиком, то там слишком много переделывать. Сообщение отредактировано: Федосеев Павел - 24.04.2012 18:47 |
olven |
![]()
Сообщение
#20
|
Новичок ![]() Группа: Пользователи Сообщений: 18 Пол: Женский Репутация: ![]() ![]() ![]() |
1) hi/lo - hi - возвращает старший байт слова (для типа word) или старшее слово (для типа longint). В контексте данной процедуры - старший байт слова (word). - lo - аналогично hi, только возвращает младшую часть. В нашем случае младший байт слова. 2) В процедуре умножения в дополнительном коде как такового нет. В самом начале процедуры выясняются знаки множителей (Sign1 и Sign2) и вычисляется знак результата (SignRes). Далее берётся модуль каждого множителя (LongBin_Abs) и перемножаются именно модули (положительные числа). После перемножения, если нужно (SignRes == TRUE) результат делается отрицательным - переводится в дополнительный код. В принципе, при умножении в столбик мы тоже так и поступаем - умножаем модули чисел и определяем знак результата. 3) Если будет достаточно показать входные числа, затем их абсолютные значения, абсолютное, а затем и знаковое значение произведения, то см. в аттаче. Если требуется показать всё умножение столбиком, то там слишком много переделывать. плохо.. ладно, понятно.. спасибо |
![]() ![]() |
![]() |
Текстовая версия | 20.07.2025 18:40 |