Russian Qt Forum

Программирование => С/C++ => Тема начата: alexman от Октябрь 06, 2011, 18:36



Название: Трабла с double.
Отправлено: alexman от Октябрь 06, 2011, 18:36
Вот код:
Код:
const double max = 673271033142181888.000000;
const double left = -976.233463;
const double min = -673271033142181888.000000;
const double right = max - (left - min);
qDebug() << QString("%1").arg(right, 0, 'f');
Выводит "1024", а должно "976.233463". Что за фигня?


Название: Re: Трабла с double.
Отправлено: LisandreL от Октябрь 06, 2011, 19:00
Потеря точности при вычислении.


Название: Re: Трабла с double.
Отправлено: alexman от Октябрь 06, 2011, 19:02
Понятно что потеря. Че делать то (кроме деления на 10^x)?


Название: Re: Трабла с double.
Отправлено: Pretorean от Октябрь 07, 2011, 09:24
Понятно что потеря. Че делать то (кроме деления на 10^x)?
используй другой тип данных


Название: Re: Трабла с double.
Отправлено: LisandreL от Октябрь 07, 2011, 10:06
Че делать то (кроме деления на 10^x)?
Вычислять right как right = max + min - left;  ;)
А вообще:
1) вычислять без значительной потери точности;
2) не использовать разный порядок операций в одних и тех же формулах в зависимости от значений (порядка значений) аргументов
3) использовать арифметику с плавающей точкой
Выбирайте любые 2.


Название: Re: Трабла с double.
Отправлено: alexman от Октябрь 07, 2011, 11:14
Понятно что потеря. Че делать то (кроме деления на 10^x)?
используй другой тип данных
Какой?


Название: Re: Трабла с double.
Отправлено: alexman от Октябрь 07, 2011, 11:17
Цитировать
1) вычислять без значительной потери точности;
2) не использовать разный порядок операций в одних и тех же формулах в зависимости от значений (порядка значений) аргументов
Не понятно?

Цитировать
3) использовать арифметику с плавающей точкой
Выбирайте любые 2.
При переходе на float потеря точности произойдет!


Название: Re: Трабла с double.
Отправлено: LisandreL от Октябрь 07, 2011, 12:10
При переходе на float потеря точности произойдет!
Да, float тоже тип с плавающей точкой.

Не понятно
Выбирайте любые 2 значит, что для 2 из 3 требований решение найти можно. Для всех 3 - едва ли.

Выбираем 1 и 2, отказываемся от 3.
Т.е. отказываемся от типов с плавающей точкой (float, real, double...) и используем (или пишем сами) библиотеку для работы с числами произвольной точности.
http://ru.wikipedia.org/wiki/%D0%94%D0%BB%D0%B8%D0%BD%D0%BD%D0%B0%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B0

Выбираем 1 и 3, отказываемся от 2.
Надо думать в каком порядке производить действия.
Например для
const double max = 673271033142181888.000000;
const double left = -976.233463;
const double min = -673271033142181888.000000;
const double right = max + min - left;

А для
const double max = 976.233463;
const double left = 673271033142181888.000000;
const double min = -673271033142181888.000000;
const double right = max - (left - min);

Выбираем 2 и 3, отказываемся от 1.
Самый простой вариант. :D
Соглашаемся на потерю точности. Ну 1024 вместо 976.233463 и 1024.


Название: Re: Трабла с double.
Отправлено: Igors от Октябрь 07, 2011, 14:40
Выводит "1024", а должно "976.233463". Что за фигня?
Ну можно долго пояснять что, мол, "все работает в определенных пределах", "не существует задачи без ограничений" и.т.д и.т.п., но лучше просто полагать что все достаточно грамотны и по крайней мере слышали что такое характеристика и мантисса.

Поэтому если стоит задача работать с такими большими числами - то надо так в теме и говорить, и то уже др. разговор. А если такой необходимости нет - то скромно уменьшить пределы, учитывая что возводить число в квадрат почти всегда придется.

А пока "фигня у коня"  :)


Название: Re: Трабла с double.
Отправлено: alexman от Октябрь 07, 2011, 15:43
Всем спасибо! По ходу надо использовать либу для работы с большими числами, так как точность важна и большие числа это нормальная ситуация в моем случае! Вариант с перестановкой слагаемых не катит (это лишь один пример)  :( Тогда другой вопрос: посоветуйте хорошую либу для данных целей и что происходит с производительностью?


Название: Re: Трабла с double.
Отправлено: SASA от Октябрь 08, 2011, 12:34
Например, http://citkit.ru/package/gmp/ (http://citkit.ru/package/gmp/)
Сам не пробовал. Если подключишь - опиши процесс.