Двойной против поплавка - PullRequest
       69

Двойной против поплавка

1 голос
/ 30 ноября 2010

В моем коде есть константа для числа пи:

const float PI = acos(-1);

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

Ответы [ 7 ]

8 голосов
/ 30 ноября 2010

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

большинству приложений не нужна большая точность, чем обеспечивает float, хотя многие предпочитают использовать double чтобы (попробовать и) замаскировать проблемы с нестабильными алгоритмами или «просто потому что» из-за неправильных представлений, таких как «операции с плавающей запятой не совсем точные».

В большинстве случаев, когда float равен «нет»достаточно точный ", проблема не в float, а в коде, который его использует.

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

4 голосов
/ 30 ноября 2010

Из стандарта:

Существует три типа плавающих точек: float, double и long double. тип double обеспечивает как минимум столько же Точность как поплавок, а типа длинный двойник дает как минимум столько же точность как двойная.

Из трех (обратите внимание, что это идет рука об руку с 3 версиями acos) вы должны выбрать long double, если вы стремитесь к точности (но вы также должны знать, что после некоторой степени, дальнейшая точность может быть избыточным в некоторых случаях).

Так что вы должны использовать это, чтобы получить наиболее точный результат из acos

long double result = acos(-1L);

(Примечание. Могут быть некоторые специфичные для платформы типы или определенные пользователем типы, которые обеспечивают большую точность)

2 голосов
/ 30 ноября 2010

Я бы хотел, чтобы константа была точной.

Нет ничего лучше точных значений с плавающей запятой.Они не могут быть сохранены с идеальной точностью из-за их представления в памяти.Это возможно только с целыми числами.double даст вам вдвое большую точность, чем float предложения (кто бы мог догадаться).double должен соответствовать вашим потребностям практически в каждом случае.

Я бы рекомендовал использовать M_PI из <cmath>, который должен быть доступен во всех реализациях стандарта, соответствующих POSIX.

1 голос
/ 30 ноября 2010

Вопрос сводится к тому, сколько точности вам нужно?

Давайте цитата из Википедии :

Например, десятичный представление π усечено до 11 десятичные знаки достаточно хороши, чтобы оценить окружность любого круг, который вписывается в Землю с ошибка менее одного миллиметра, и десятичное представление π усечено до 39 знаков после запятой достаточно, чтобы оценить окружность любого круга, который подходит в наблюдаемой вселенной с точность сопоставима с радиусом атом водорода.

Я написал небольшую Java-программу , вот ее вывод:

As string: 3.14159265358979323846264338327950288419716939937510
As double: 3.141592653589793
As float:  3.1415927

Помните , что если вы хотите иметь двойную точность double , все ваши числа, с которыми вы рассчитываете, также должны быть doubles . (Это не совсем верно, но достаточно близко.)

1 голос
/ 30 ноября 2010

Это точно зависит , насколько точно вы должны быть.Мне никогда не приходилось удваивать, потому что числа с плавающей точкой недостаточно точны.

Наиболее точное представление числа пи равно M_PI из math.h

0 голосов
/ 30 ноября 2010

Для большинства приложений float прекрасно подойдет для PI. Double, безусловно, обладает большей точностью, но он не гарантирует точности больше, чем это может делать float. Под этим я подразумеваю, что число 1.0, представленное в двоичном виде, не является рациональным числом. Поэтому, если вы попытаетесь представить его, вы получите только n-ю цифру, где n определяется тем, сколько байтов вы используете для представления этого числа.

К сожалению, чтобы содержать много цифр PI, вам, вероятно, придется держать его в строке. Хотя сейчас мы говорим о некоторых впечатляющих числах, которые вы можете увидеть при моделировании молекул. Вам, вероятно, не понадобится такой уровень точности.

0 голосов
/ 30 ноября 2010

Как говорит этот сайт, существует три перегруженных версии функции acos.

Поэтому вызов acos (-1) неоднозначен.

Сказав это,Вы должны объявить PI как long double, чтобы избежать потери точности, используя

   const long double PI = acos(-1.0L);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...