Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование double вместо float, повысится ли точность вычислений? 
:(
    Опции темы
Нитонисе
Дата 26.8.2012, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: нет
Всего: 2



В моих программах часто выполняются различные расчеты. Нередко встречаются очень маленькие цифры (например первая значащая цифра появляется в десятом знаке после запятой) и мне нужна достаточная точность, что бы 0.00000000001 не стало вдруг нулем. Сейчас я всегда использую тип float и вижу что часто присваивая переменно например 1 на деле могу получить 1.999999856752. В подавляющем большинстве случаев это приемлемая точность, но тем не менее было бы здорово, если бы вычисления стали еще точнее. Поможет ли мне в этом double или этот тип всего лишь увеличивает емкость, позволяя использовать бОльшие числа?
PM MAIL   Вверх
boostcoder
Дата 26.8.2012, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(Нитонисе @  26.8.2012,  12:50 Найти цитируемый пост)
Поможет ли мне в этом double

нет. создаст еще больше проблем.

для подобных задач существует прекрасная и очень сильно проверенная библиотека GMP.
ну или на худой конец, переходи на использование std::complex.
PM WWW   Вверх
Фантом
Дата 26.8.2012, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: нет
Всего: 49



Цитата(Нитонисе @  26.8.2012,  13:50 Найти цитируемый пост)
В подавляющем большинстве случаев это приемлемая точность, но тем не менее было бы здорово, если бы вычисления стали еще точнее. Поможет ли мне в этом double или этот тип всего лишь увеличивает емкость, позволяя использовать бОльшие числа? 

Если механически везде поменять float на double, то где-то поможет, а где-то, наоборот, ухудшит ситуацию. При грамотном использовании - поможет.

Но лучше давайте сразу отделим мух от котлет. Вам нужна относительная погрешность вычислений 10^{-10} или абсолютная погрешность 10^{-10} (с сравнительно большей относительной)? В первом случае без double не обойтись, во втором - float вполне может и хватить.
PM   Вверх
kosmonaFFFt
Дата 27.8.2012, 07:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(boostcoder @  26.8.2012,  16:56 Найти цитируемый пост)
ну или на худой конец, переходи на использование std::complex.

А чем поможет std::complex? Он ведь тоже базируется на double, float и т. д.


--------------------
user posted image
PM MAIL ICQ   Вверх
math64
Дата 27.8.2012, 07:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Лучше с самого начала везде использовать double - кроме массивов и других случаев, когда нужно экономить память.
Все функции из math.h работают с double - при их вызове float конвертируется в double, а результат наоборот.
Регистры математического сопроцессора имеют тип long double, команды сохранения из его регистра в float и загрузки из float более медленные.
Так что с double будет работать не только точнее, но и чуть быстрее.
А если точности double не хватает - нужна специализированная библиотека.
PM   Вверх
Alexeis
Дата 27.8.2012, 08:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Не всегда поможет. Числа float и double имеют фиксированное число цифр. Например если к числу 9 000 000 прибавить 0. 000 009, то мы потеряем младшую часть, она будет попросту отброшена хоть то float, хоть то double. Бывает, что при вычислениях такие прибавления или умножения делаются в качестве промежуточных вычислений, а конечный результат малый. В этом случае можно получить погрешность в 1000% и больше. Кроме того на точность вычислений еще влияют настройки сопроцессора. Например при подключении DirectX автоматически снижается точность всех флоат вычислений и даже дабл будут считаться с точностью флоатов. Также потери точности легко добиться при возведении чисел в степень. Возвели в квадрат или куб, че нить прибавили, извлекли корень и младшие разряды пошли по бороде.

Добавлено через 4 минуты и 58 секунд
Цитата(math64 @  27.8.2012,  08:44 Найти цитируемый пост)
Так что с double будет работать не только точнее, но и чуть быстрее.

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


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Нитонисе
Дата 27.8.2012, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: нет
Всего: 2



Цитата(boostcoder @  26.8.2012,  12:56 Найти цитируемый пост)
для подобных задач существует прекрасная и очень сильно проверенная библиотека GMP

А есть где-то обзор данной библиотеки на русском? И есть ли смысл полностью заменить float на данный тип? Речь идет о скорости вычислений и занимаемой памяти. Может быть уместно разделять задачи, где нужна повышенная точность и использовать там GMP и менее важные вычисления, где и float сойдет?

Цитата(Фантом @  26.8.2012,  15:36 Найти цитируемый пост)
Вам нужна относительная погрешность вычислений 10^{-10} или абсолютная погрешность 10^{-10} (с сравнительно большей относительной)?

Мне нужна точность хотябы в 10-ом знаке после запятой, чего float не позволяет. Порой заведомо зная что в некоторой части вычислений будут малые числа я специально их увеличиваю в 100 000 раз, чтобы программа не сочла где-то что значением малого числа можно пренебречь и приравнять его к нулю, в результате чего бывает ошибка деления на ноль.

Попутный вопрос. Имеет ли смысл увеличивать числа типа float с целью увеличения точности? Вот если записать float a=1, то можно получить a=0.99999957482. А если записать float a=100000, ведь не получится a=99999.957482, скорее что-то типа а=99999.99999957482. 

Это сообщение отредактировал(а) Нитонисе - 27.8.2012, 10:22
PM MAIL   Вверх
Alexeis
Дата 27.8.2012, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(Нитонисе @  27.8.2012,  11:21 Найти цитируемый пост)
Попутный вопрос. Имеет ли смысл увеличивать числа типа float с целью увеличения точности?

-  Нет. числа float отдельно хранят значащие цифры, отдельно степень. Просто увеличиться значение степени. float хранит 7-8 десятичных цифр. double что-то около 15-16. Чтобы сказать точнее нужно смотреть спецификацию. По степени запас флоата 10^38й степени. Точность в 10м знаке обеспечит только double (long double) и то если не будет операций умножения на большие числа или возведения в степень.

Добавлено через 4 минуты и 41 секунду
Можно кстати википедию почитать http://ru.wikipedia.org/wiki/%D0%A7%D0%B8%...%82%D0%BE%D0%B9
Более подробно описано.

Это сообщение отредактировал(а) Alexeis - 27.8.2012, 10:37


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Фантом
Дата 27.8.2012, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: нет
Всего: 49



Цитата(Нитонисе @  27.8.2012,  11:21 Найти цитируемый пост)

Мне нужна точность хотябы в 10-ом знаке после запятой, чего float не позволяет. 

Вот меня и интересует, что Вы под этим понимаете. Вообще говоря, float позволяет работать с числами до 10^{-38}. только вот относительная погрешность будет плохой.

Цитата(Нитонисе @  27.8.2012,  11:21 Найти цитируемый пост)

Попутный вопрос. Имеет ли смысл увеличивать числа типа float с целью увеличения точности? Вот если записать float a=1, то можно получить a=0.99999957482. А если записать float a=100000, ведь не получится a=99999.957482, скорее что-то типа а=99999.99999957482. 

Нет, это бессмысленно. Иногда можно добиться некоторого улучшения точности, добившись того, чтобы все числа были близки к 1, но вот обратный процесс ничего полезного не даст.

P.S. Кстати, полезно иметь в виду, что 99% проблем такого рода решаются не выбором типов, библиотек и т.п., а разумным преобразованием алгоритма вычислений. 
PM   Вверх
Нитонисе
Дата 27.8.2012, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: нет
Всего: 2



Цитата(Фантом @  27.8.2012,  11:08 Найти цитируемый пост)
Вот меня и интересует, что Вы под этим понимаете.

Я может не совсем понимаю об чем речь smile Мне хотелось бы, чтобы умножая 10^{-10} на 10^{-10} я бы получил 10^{-20}.
PM MAIL   Вверх
Alexeis
Дата 27.8.2012, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(Фантом @  27.8.2012,  12:08 Найти цитируемый пост)
Вот меня и интересует, что Вы под этим понимаете. Вообще говоря, float позволяет работать с числами до 10^{-38}. только вот относительная погрешность будет плохой.

  Относительная погрешность постоянная. Она вычисляется как отношение погрешности к самой величине. Величина увеличилась, ну так и погрешность увеличилась пропорционально, а отношение сохранилось.

Добавлено @ 11:54
Цитата(Нитонисе @  27.8.2012,  12:43 Найти цитируемый пост)
Мне хотелось бы, чтобы умножая 10^{-10} на 10^{-10} я бы получил 10^{-20}. 

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


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Нитонисе
Дата 27.8.2012, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: нет
Всего: 2



Цитата(Alexeis @  27.8.2012,  11:53 Найти цитируемый пост)
Так и будет. Числа с плавающей точкой как раз для этого. Вопрос лишь сколько значащих цифр нужно сохранять.

Да нет, так не будет. Получается что-то типа 0.9999995742 Е-20.
PM MAIL   Вверх
Фантом
Дата 27.8.2012, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: нет
Всего: 49



Цитата(Нитонисе @  27.8.2012,  12:43 Найти цитируемый пост)

Я может не совсем понимаю об чем речь smile Мне хотелось бы, чтобы умножая 10^{-10} на 10^{-10} я бы получил 10^{-20}. 


float для этого более чем достаточно.

Цитата(Нитонисе @  27.8.2012,  13:15 Найти цитируемый пост)

Да нет, так не будет. Получается что-то типа 0.9999995742 Е-20. 


Ну да, правильно. А что, собственно, Вы планировали получить? Операнды имеют относительную погрешность около 10^{-6}, при перемножении относительные погрешности складываются, соответственно, относительная погрешность результата имеет тот же порядок.

Добавлено через 2 минуты и 5 секунд
Цитата(Alexeis @  27.8.2012,  12:53 Найти цитируемый пост)

  Относительная погрешность постоянная. Она вычисляется как отношение погрешности к самой величине. Величина увеличилась, ну так и погрешность увеличилась пропорционально, а отношение сохранилось.

Не совсем. На границах возможных значений типа относительная погрешность в любом случае будет расти.
PM   Вверх
Нитонисе
Дата 27.8.2012, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: нет
Всего: 2



Цитата(Фантом @  27.8.2012,  12:20 Найти цитируемый пост)
Ну да, правильно. А что, собственно, Вы планировали получить?

А планировал получить 1 Е-20 smile Собственно именно так я понимаю точность вычислений. У меня программа выполняет инженерные расчеты. Много возведений в степень, извлечений корней, тригонометрических функций, короче весь математический арсенал используется очень сильно. И вот в результате расчета я получаю некоторые величины. Существует проверка этих величин. Подставляя их в некоторые выражения я должен получить ноль. Но из-за всех этих неточностей вычисления у меня чистый ноль не получается. Может получиться 0.0001 или 0.1 (в зависимости от порядка тех самых первоначально искомых величин).
PM MAIL   Вверх
math64
Дата 27.8.2012, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Цитата(Нитонисе @  27.8.2012,  12:15 Найти цитируемый пост)
Да нет, так не будет. Получается что-то типа 0.9999995742 Е-20.

В float под мантиссу выделяется 23 бита, это  6 знаков с небольшим запасом в десятичной системе. При умножении относительная погрешность удваивается.
Вот и получаете 6 знаков точности.
У long double - мантисса 64 бита, примерно 18 знаков точность. больше без спец. библиотеки не получите.
Денежные суммы можно хранить в копейках вместо рублей, чтобы не было ошибок округления, В других случаях умножение на коэффициент обычно не поможет.

Если решаешь уравнение:
X^2 + 2000*X + 1 = 0;
X1 = 1000 + sqrt(999999);
X2 = 1000 - sqrt(999999);
X2 лучше вычислять по формуле X2 = 1 / X1;

PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1429 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.