Форум «Всё о Паскале» _ Ада и другие языки _ Вычисление с ограниченной разрядностью.
Автор: Krjuger 16.03.2011 21:41
Составить программу на алгоритмическом языке, моделирующую вычисления на ЭВМ с ограниченной разрядностью m. Используя эту программу найти значения машинного нуля, машинной бесконечности, машинного эпсилон . Составить график зависимости относительной погрешности от количества разрядов m= 4,5,…8. Я собираюсь сделать эту зачаду на С++,но возникли проблемы на этапе разработки,а именно,у меня не совсем получается представить структуру.На сколько я понимаю,любое число в памяти представляется как 1 бит на знак +-,m разрядов идет мантиса,потом еще 1 бит на знак степени двойки,затем n-ое число разрядов,в которых храниться степерь двойки(p),а само число представляется в виде x=m*2p. Насколько я понимаю погрешность будет появляться после того как число из нормального вида будет переводиться в вид,в котором оно храниться в памяти,а потом востанавливаться и сравниваться с исходным,так будет определяться погрешность.Проблемы возникли в том,как преобразовывать число в обе стороны,у меня даже дельных идей нету,так что буду рад хоть какой то идее,с более менее простой реализацией.
P.S. Забыл сказать,на входе может быть любое вещественное число.
Автор: TarasBer 16.03.2011 22:48
> любое число
Только вещественное с плавающей запятой.
> в памяти представляется как 1 бит на знак +-,m разрядов идет мантиса,потом еще 1 бит на знак степени двойки
Знак числа и знак экспоненты идут подряд.
> Насколько я понимаю погрешность будет появляться после того как число из нормального вида будет переводиться в вид,в котором оно храниться в памяти,а потом востанавливаться и сравниваться с исходным,так будет определяться погрешность.
1. Что такое "нормальный вид"? Целочисленный? Вещественный с фиксированной запятой? Вещественый десятичный с плавающей запятой?
2. в котором оно хранится в памяти, а не "хранитЬся"
Автор: Krjuger 17.03.2011 1:37
Спасибо за ваш коментарий.Из всего, что вы написали для меня информативным было только.
Цитата
Знак числа и знак экспоненты идут подряд.
На пункт 1 вы сами ответили.
Цитата
> любое число
Только вещественное с плавающей запятой.
Насчет пункта 2,грамотность это немаловажная часть,но щас для меня несколько важнее другой вопрос....а именно сама задача.
Автор: Lapp 17.03.2011 2:17
Цитата(Krjuger @ 16.03.2011 21:37)
для меня несколько важнее другой вопрос....а именно сама задача.
Законно ). Скажи - тебе нужно самому организовывать хранение числа или можно просто обрезать обычное действительное число (занулить лишние разряды)? Если первое, то - как? Как ты предполагаешь делать доступ внутрь байта, например? Я не говорю, что это невозможно или трудно , просто нужно бы уточнить.
Автор: Krjuger 17.03.2011 4:50
Давайте я тогда уточню что в задании является главным. Целью этой задачи является не само моделирование вычисления на ЭВМ,а изучение(сбор данных) того,как влияет на относительную погрешность количество разрядов мантисы,причем четких предписаний о том,как это делать нету.
Цитата
можно просто обрезать обычное действительное число (занулить лишние разряды)?
Если я правильно понял,вы имеете ввиду то,что у нас есть число с 16 знаками после запятой( например) и разрядов мантисы 5,то мы просто откинем 11 последних чисел? Если вы имели в виду это,то нет,это будет неправильным. Я наверно приведу пример: Допустим у нас есть число x=3.1 в десятичной системе. Слачала мы переводим целую часть в двоичную систему,3=11,потом дробную 0.1=0.0(0011),как мы видим это число бесконечное.Дальше мы обьединяем целую и дробную части получаем 11.0001100110011 и тд,сдвигаем на 2 разряда,это будет равно 0.11000110011*210,число после точки и до множителя 2 и будет мантисой.Дальше в зависимости от разрядности ЭВМ мы записываем n-е количество цифр в мантису и наше число будет выглядеть как то так. | |1|1|0|0|0|1|1|0|0|1|1| |0|0|.....|1|0| первый пустой квадрат это знакчисла в нашем случае 0,дальше мантиса,я написал для разрядности 11,дальше знак экспоненты и дальше уже сама степень. Насчет того как расположены знаки мантисы и экспонены,я не знаю точно,в лекциях давали так,как я написал, TarasBer сказал ,что по другому,чья истина,я не знаю.
В общем,получив такое разложение числа,мы его потом опять преобразуем в исходный вид и потом сравниваем их.
Самое первое,что приходит в голову это записывать все в одномерный массив с заданными параметрами,но что то мне подсказывает,что это далеко не лучшая идея и при вычислении машинного нуля, машинной бесконечности, машинного эпсилон будет происходить переполнение массива.
Автор: Lapp 17.03.2011 9:40
Цитата(Krjuger @ 17.03.2011 0:50)
Давайте я тогда уточню что в задании является главным. Целью этой задачи является не само моделирование вычисления на ЭВМ,а изучение(сбор данных) того,как влияет на относительную погрешность количество разрядов мантисы,причем четких предписаний о том,как это делать нету.
Если честно, мне не совсем понятно, что тут изучать. В смысле, что изучать на компьютере. На мой взгляд, тут все прекрасно можно сказать и без него. Но, раз такое задание - значит, такое задание, и перечить я не собираюсь. А говорю это я только потому, что не понимаю, что ты имешь в виду дальше..
Цитата
Если я правильно понял,вы имеете ввиду то,что у нас есть число с 16 знаками после запятой( например) и разрядов мантисы 5,то мы просто откинем 11 последних чисел? Если вы имели в виду это,то нет,это будет неправильным.
Meis pour quoi?? (только не чисел все-таки, а цифр, а еще точнее - двоичных разрядов) Хорошо, смотрим твой пример..
Цитата
Я наверно приведу пример: Допустим у нас есть число x=3.1 в десятичной системе. Слачала мы переводим целую часть в двоичную систему,3=11,потом дробную 0.1=0.0(0011),как мы видим это число бесконечное.Дальше мы обьединяем целую и дробную части получаем 11.0001100110011 и тд,сдвигаем на 2 разряда,это будет равно 0.11000110011*210,число после точки и до множителя 2 и будет мантисой.Дальше в зависимости от разрядности ЭВМ мы записываем n-е количество цифр в мантису и наше число будет выглядеть как то так. | |1|1|0|0|0|1|1|0|0|1|1| |0|0|.....|1|0| первый пустой квадрат это знакчисла в нашем случае 0,дальше мантиса,я написал для разрядности 11,дальше знак экспоненты и дальше уже сама степень. Насчет того как расположены знаки мантисы и экспонены,я не знаю точно,в лекциях давали так,как я написал, TarasBer сказал ,что по другому,чья истина,я не знаю. В общем,получив такое разложение числа,мы его потом опять преобразуем в исходный вид и потом сравниваем их.
Иии.... что? Ну, перевел ты 3.110 в двоичную СС (надеюсь, правильно)) - и что? Ты просто хотел показать, как это делается, что ли? Ты правда думаешь, что мы тут не в курсе? Короче, то ли ты забыл сделать вывод, который делал, то ли его просто, извини, нет..
Кхм.. А может, ты подумал, что я предлагаю занулять десятичные разряды? и старался показать, что в двоичной СС это выглядит иначе?.. Эта гипотеза несколько проясняет твой монолог . Но тогда имей в виду, что я говорил, конечно же, о двоичных разрядах (а о чем еще можно вообще говорить, если речь идет о машинном представлении чисел?? )
Цитата
Самое первое,что приходит в голову это записывать все в одномерный массив с заданными параметрами,но что то мне подсказывает,что это далеко не лучшая идея и при вычислении машинного нуля, машинной бесконечности, машинного эпсилон будет происходить переполнение массива.
Можно и так, конечно. Но тогда (я думаю) тебе придется самому реализовать всю арифметику для таких чисел (если ты собираешься экспериментировать с точностью вычислений). Под "переполнением массива" (интересный термин)) ты, по-видимому, имел в виду возможный вынос единицы за разрядную сетку (переполнение _числа_, отсюда и твой термин)) и связанную с этим Range Check Error. Но с этим легко бороться простым добавлением лишнего разряда (как, собсно, и сделано на самом деле в реальных процессорах). Если использовать _уже_готовое_ представление действительных чисел (с обрезанием справа и учетом краевого эффекта), то арифметику писать не нужно - она тоже _уже_готова_.
Автор: TarasBer 17.03.2011 17:24
> а изучение(сбор данных) того,как влияет на относительную погрешность количество разрядов мантисы,причем четких предписаний о том,как это делать нету.
Я правильно понимаю, что тебе достаточно разобрать 3 случая - 4, 8 и 10-байтовые числа? Для того, чтобы сравнить результат вычислений с разной погрешностью, изначально всегда храни числа в long long float, а перед вычислением просто устанавливай 8087CW на нужный режим.
> 1. Что такое "нормальный вид"? Целочисленный? Вещественный с фиксированной запятой? Вещественый десятичный с плавающей запятой? > На пункт 1 вы сами ответили.
Нормальный - это вещественный с плавающей запятой? Так он так и хранится в памяти, то есть при переводе никакой погрешности проявиться не может.
А для вычисления машинного нуля и машинного епсилон и этого не надо.
float (или long float, или long long float) a = 1.0; while (float или другой вещ. тип)1.0 + a != (float или другой вещ. тип)1.0 { a *= 0.5; };
Правда, всё равно перед этим надо переключить сопроцессор на максимальную точность.
Автор: Lapp 17.03.2011 18:38
Цитата(TarasBer @ 17.03.2011 13:24)
Я правильно понимаю, что тебе достаточно разобрать 3 случая - 4, 8 и 10-байтовые числа?
Мне кажется, не совсем.. Автор темы говорил:
Цитата
Составить график зависимости относительной погрешности от количества разрядов m= 4,5,…8.
Разрядов (я полагаю, двоичных), а не байт. И при чем тут тогда "4, 8 и 10-байтовые числа"?
Автор: TarasBer 17.03.2011 18:58
Ну тогда пусть вычисления ведёт для long long float, а после каждой операции обнуляет последние 64-минус-точность байт.
Автор: Krjuger 18.03.2011 0:25
Цитата
Если честно, мне не совсем понятно, что тут изучать. В смысле, что изучать на компьютере. На мой взгляд, тут все прекрасно можно сказать и без него. Но, раз такое задание - значит, такое задание, и перечить я не собираюсь.
Если чесно, сам предмет связан с программированием весьма посредственно.Численные методы называется) TarasBer,Вы наверно не совсем меня понимаете. Реч не о 4,8,10 байтовых числах. А именно,как сказал Lapp, о разрядности мантисы.
Цитата
Для того, чтобы сравнить результат вычислений с разной погрешностью, изначально всегда храни числа в long long float, а перед вычислением просто устанавливай 8087CW на нужный режим.
Если чесно после long long float я не понял ничего)))Если можно ,привидите хоть какой то простенький пример. Кстати у меня лично после того как я написал long long float выдало следующую ошибку.
Цитата
Error 1 error C2632: '__int64' followed by 'float' is illegal
а long float работает нормально. Но воспользовавшись кодом TarasBer я получил весьма интересные результаты. http://saveimg.ru/show-image.php?id=c96936b283a0872547af5d7a0dca7675
Цитата
Правда, всё равно перед этим надо переключить сопроцессор на максимальную точность
Возможно это именно из-за этого,но я чесно не знаю как это сделать.
Автор: TarasBer 18.03.2011 1:51
А, это long double называется, короче 80-разрядный вещественный. Ты картинку залил неправильно. Ты своё сообщение хоть проверял?
Для того, чтобы перевести сопроцессор в режим максимальной точности, надо задать ему контрольное слово, равное 0x133F
Если я правильно понял,вы имеете ввиду то,что у нас есть число с 16 знаками после запятой( например) и разрядов мантисы 5,то мы просто откинем 11 последних чисел? Если вы имели в виду это,то нет,это будет неправильным. Я наверно приведу пример: ...
Вообще-то с точки зрения "как влияет на относительную погрешность количество разрядов мантисы" то, что предложил Lapp и то, что предлагаешь ты, абсолютно эквивалентно. Просто потому, что с точки зрения погрешности взаимное расположение мантиссы, порядка и знака никакой роли не играет. Но вариант Lapp'а в десятки (а то и сотни) раз эффективнее с вычислительной точки зрения и проще реализуется.
Автор: Гость 19.03.2011 15:16
> Но воспользовавшись кодом TarasBer я получил весьма интересные результаты.
Фигню ты получил. Ты только при выводе числа меняешь точность, а надо её при расчётах править. То есть так:
while (cut(1.0 + a, 64-точность) != 1.0) do a*=0.5;