Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

вещественные числа с плавающей точкой

17K
30 июня 2010 года
LostAngel
7 / / 10.10.2006
Работаю над проектом, требующим большую точность вычисления вещественных чисел.
Решил использовать long double в надежде получить точность побольше.
Столкнулся с тем, что просто невозможно получить желаемую точность.

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

операционная система Windows XP
компилятор Borland C++ 6.0

результат

sizeof(long double);

10.

т.е. для типа long double отводится 10 байт.

для представления одной цифры нам необходимо 4 бита ( т.е. всего 10 возможных комбинаций, 2^3=8 -недостаточно, 2^4=16 )

в итоге - 4 бита на цифру, 1 байт на две цифры, 10 байт на 20 цифр.
т.е. выходит, мы можем записать в переменную long double 20 значащих цифр.

и этого бы мне хватало для моей задачи. с рассчетом на правильность таких размышлений я создаю программу и проверяю ее точность. а точности, можно сказать, и нет. по крайней мере ни о каких 20 значащих цифр речи не идет.

начинаем копаться в проблеме, обращаемся к теории.
источник - Надежда Голубь - "Искусство программирования на асемблере". 39 страница.
рисунок, объясняющий, что для записи числа используются 10 байт, т.е. 80 бит, из них 1 определяет знак числа, 15 определяют "степень", а само число записывается в оставшихся 64 битах.

анализируя имеющиеся данные, вычисляем - 64 бита, по 4 бита на цифру, получаем 64/4 = 16 значащих цифр.

но в той же книжке несколькими строками ниже - можно представить 19-20 цифр.... но как? если степень всегда записывается, даже если она равна нулю?

все это теоретические размышления и вопросы, требующие четкого однозначного и ясного ответа, который никак не находится.

на практике же мы получаем вот такую штуку:

Цитата:
x = 1.102540L;
y = -1.10130L;
c = x + y;
fprintf(file1, "%.18Le", c);




и получаю в результате

1.240000000000129887e-03

а хотелось бы получить

1.240000000000000000e-03


помогите советом - чтобы такое почитать, чтобы эту тему знать "на все сто" и посоветуйте библиотеку на С++ (желательно) для работы с вещественными числами большей точности. В boost есть "рациональные числа", но не знаю на сколько использование такой библиотеки мне поможет.

поспрашивал в других местах, говорят мол - это все из за представления чисел в компьютере и баста, мол, ничего с этим не сделать. но как-то же проводят более точные вычисления? каждый раз пишут свой тип данных?
да и опять же, ну точность в 16 значащих цифр - но ее же все равно нет. на практике точность - 13 значащих цифр. а то и еще меньше, это в моем примере 13 остается точных.

62K
30 июля 2010 года
glonnawancy
5 / / 14.07.2010
Формула-то точна, а в сопроцессор не любые числа влезают : А если использовать длинную арифметику, так не всё ли равно - складывать по определению или возводить в степень по формуле? Кстати, если будут оценки, что быстрее - тоже интересно.
2.1K
30 июля 2010 года
Norgat
452 / / 12.08.2009
Цитата:
поспрашивал в других местах, говорят мол - это все из за представления чисел в компьютере и баста, мол, ничего с этим не сделать. но как-то же проводят более точные вычисления? каждый раз пишут свой тип данных?
да и опять же, ну точность в 16 значащих цифр - но ее же все равно нет. на практике точность - 13 значащих цифр. а то и еще меньше, это в моем примере 13 остается точных.



вообще то точность 16 цифр...
т.к. 1.240000000000129887e-03, если записать в обычной для нас форме будет иметь вид:

0,001240000000000129887

жирным я выделил ошибку вычислений...
так что точность в 16 знаков соблюдается, по крайней мере на этом примере.

п.с. хотя Шилдт, по поводу диапазона long double пишет: 10 значащих цифр(минимальный диапазон)
у Рэя Лишнера по поводу конкретной точности вообще ничего нет, только приписка о том, что точность long double не меньше точности double.

п.с.с. интерпретатор haskell выдаёт результат с той же погрешностью, что и C++, так что возможно эти ошибки появляются из-за неточностей вычислений сопроцессора.

5
30 июля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: LostAngel
Работаю над проектом, требующим большую точность вычисления вещественных чисел.
Решил использовать long double в надежде получить точность побольше.
Столкнулся с тем, что просто невозможно получить желаемую точность.



Однозначно изучать матчасть.


Для повышенной точности используются типы с фиксированной запятой. В .NET например для этого используется тип Decimal. Полагаю что в C++ Builder просто обязан быть аналог.

10
30 июля 2010 года
Freeman
3.2K / / 06.03.2004
В тему.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог