вещественные числа с плавающей точкой
Решил использовать 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 цифр.... но как? если степень всегда записывается, даже если она равна нулю?
все это теоретические размышления и вопросы, требующие четкого однозначного и ясного ответа, который никак не находится.
на практике же мы получаем вот такую штуку:
y = -1.10130L;
c = x + y;
fprintf(file1, "%.18Le", c);
и получаю в результате
1.240000000000129887e-03
а хотелось бы получить
1.240000000000000000e-03
помогите советом - чтобы такое почитать, чтобы эту тему знать "на все сто" и посоветуйте библиотеку на С++ (желательно) для работы с вещественными числами большей точности. В boost есть "рациональные числа", но не знаю на сколько использование такой библиотеки мне поможет.
поспрашивал в других местах, говорят мол - это все из за представления чисел в компьютере и баста, мол, ничего с этим не сделать. но как-то же проводят более точные вычисления? каждый раз пишут свой тип данных?
да и опять же, ну точность в 16 значащих цифр - но ее же все равно нет. на практике точность - 13 значащих цифр. а то и еще меньше, это в моем примере 13 остается точных.
да и опять же, ну точность в 16 значащих цифр - но ее же все равно нет. на практике точность - 13 значащих цифр. а то и еще меньше, это в моем примере 13 остается точных.
вообще то точность 16 цифр...
т.к. 1.240000000000129887e-03, если записать в обычной для нас форме будет иметь вид:
0,001240000000000129887
жирным я выделил ошибку вычислений...
так что точность в 16 знаков соблюдается, по крайней мере на этом примере.
п.с. хотя Шилдт, по поводу диапазона long double пишет: 10 значащих цифр(минимальный диапазон)
у Рэя Лишнера по поводу конкретной точности вообще ничего нет, только приписка о том, что точность long double не меньше точности double.
п.с.с. интерпретатор haskell выдаёт результат с той же погрешностью, что и C++, так что возможно эти ошибки появляются из-за неточностей вычислений сопроцессора.
Решил использовать long double в надежде получить точность побольше.
Столкнулся с тем, что просто невозможно получить желаемую точность.
Однозначно изучать матчасть.
Для повышенной точности используются типы с фиксированной запятой. В .NET например для этого используется тип Decimal. Полагаю что в C++ Builder просто обязан быть аналог.