C точность double: зависит от компилятора? - PullRequest
4 голосов
/ 05 апреля 2010

на моей 32-битной машине (с ядром Intel T7700 duo) у меня есть 15 прецизионных цифр для двойных и длинных двойных типов для языка C. Я сравнил параметры LDBL_DIG для длинных двойных и DBL_DIG для двойных, и они оба 15. Я получил эти ответы, используя MVS2008. Мне было интересно, могут ли эти результаты зависеть от компилятора или они просто зависят от моего процессора?

Большое спасибо ...

Ответы [ 5 ]

1 голос
/ 05 апреля 2010

Хотя стандарт C не требует этого, он НАСТОЯТЕЛЬНО РЕКОМЕНДУЕТ, чтобы float и double были стандартными типами с плавающей точкой одинарной и двойной точности IEEE 754, соответственно. Какие они есть на любой архитектуре, которая поддерживает их в аппаратном обеспечении (что означает практически везде).

С long double все немного сложнее, так как не многие архитектуры поддерживают типы с плавающей запятой с точностью выше двойной. Стандарт требует, чтобы long double имел как минимум такой же диапазон и точность, что и double. Это означает, что если архитектура больше не поддерживает ничего, тип long double идентичен double. И даже если делает (например, x87), некоторые компиляторы по-прежнему делают long double эквивалентным double (например, M $ VC), в то время как другие предоставляют расширенный тип точности как long double (например, Borland и НКУ).

Даже если компилятор предоставляет тип расширенной точности, все еще нет стандарта для того, что именно означает «расширенная точность». На х87 это 80 бит. Некоторые другие архитектуры имеют 128-битные типы с четверной точностью. Даже на x87 некоторые компиляторы имеют sizeof(long double) = 10, в то время как другие дополняют его для выравнивания, так что оно равно 12 или 16 (из 8, если long double равно double).

Итак, суть в том, что реализация long double зависит от платформы. Единственное, в чем вы можете быть уверены, это то, что оно по крайней мере эквивалентно double. Если вы хотите написать переносимый код, не зависите от его представления - держите его подальше от интерфейсов и двоичного ввода-вывода. Использование long double во внутренних вычислениях вашей программы - это нормально.

1 голос
/ 05 апреля 2010

правый. Это зависит от реализации. Единственными гарантиями стандарта C являются:

  1. float является подмножеством double, а double является подмножеством long double (6.2.5 / 10)
  2. FLT_RADIX ≥ 2 (5.2.4.2.2 / 9)
  3. FLT_DIG ≥ 6, DBL_DIG ≥ 10, LDBL_DIG ≥ 10
  4. FLT_MIN_10_EXP, DBL_MIN_10_EXP LDBL_MIN_10_EXP ≤ -37
  5. FLT_MAX_10_EXP, DBL_MAX_10_EXP, LDBL_MAX_10_EXP ≥ +37
  6. FLT_MAX, DBL_MAX, LDBL_MAX ≥ 1e+37 (5.2.4.2.2 / 10)
  7. FLT_EPSILON ≤ 1e-5, DBL_EPSILON ≤ 1e-9, LDBL_EPSILON ≤ 1e-9 (5.2.4.2.2 / 11)
  8. FLT_MIN, DBL_MIN, LDBL_MIN ≤ 1e-37

Обработка long double = double разрешена стандартом C.

1 голос
/ 05 апреля 2010

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

1 голос
/ 05 апреля 2010

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

0 голосов
/ 05 апреля 2010

Вы также должны знать, что модули с плавающей запятой некоторых ЦП поддерживают несколько уровней точности для промежуточных результатов, и этим уровнем можно управлять во время выполнения. На приложения повлияли такие вещи, как ошибочные версии библиотек DirectX, которые выбирают более низкий уровень точности во время вызова библиотеки и забывают восстановить настройку, что влияет на последующие вычисления FP в вызывающей программе.

...