Точность с плавающей точкой в ​​Visual C ++ - PullRequest
8 голосов
/ 02 апреля 2010

HI

Я пытаюсь использовать надежные предикаты для вычислительной геометрии от Джонатана Ричарда Шевчука.

Я не программист, поэтому я даже не уверен в том, что говорю, возможно, я совершаю некоторую основную ошибку.

Дело в том, что предикаты должны учитывать точную арифметику с адаптивной точностью с плавающей точкой. На моем компьютере: Asus Pro31 / S (Core Due Centrino Processor) они не работают. Проблема может заключаться в том, что мой компьютер может использовать некоторые улучшения в точности с плавающей запятой, что противоречит тому, что использовал Шевчук. Автор говорит:

/* On some machines, the exact arithmetic routines might be defeated by the  */
/*   use of internal extended precision floating-point registers.  Sometimes */
/*   this problem can be fixed by defining certain values to be volatile,    */
/*   thus forcing them to be stored to memory and rounded off.  This isn't   */
/*   a great solution, though, as it slows the arithmetic down.              */

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

Ответы [ 5 ]

3 голосов
/ 02 апреля 2010

Для Visual Studio необходим параметр компилятора /fp:strict, который отображается в IDE как Project->Properties->C/C++->Code Generation->Floating Point Model

3 голосов
/ 02 апреля 2010

Да, вам придется изменить управляющее слово FPU, чтобы избежать этого. Это хорошо объяснено для большинства популярных компиляторов на этой веб-странице . Помните, что это совершенно несовместимо с тем, что большинство библиотек ожидает от FPU, не смешивайте и не сопоставляйте. После восстановления всегда восстанавливайте управляющее слово FPU.

2 голосов
/ 02 апреля 2010

_control87(_PC_53, _MCW_PC) или _control87(_PC_24, _MCW_PC) добьются цели. Они устанавливают точность на double и single соответственно с MSVC. Возможно, вы захотите использовать _controlfp_s(...), поскольку это позволяет вам явно получить текущее управляющее слово после его установки.

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

Как уже отмечали другие, вы можете справиться с этим, установив управляющее слово x87 для ограничения точности с плавающей запятой. Однако лучшим способом было бы заставить MSVC генерировать код SSE / SSE2 для операций с плавающей запятой; Я удивлен, что он не делает этого по умолчанию в наши дни, учитывая преимущества в производительности (и тот факт, что он предотвращает возникновение досадных ошибок, подобных тому, что вы видите), но MSVC не учитывает идиосинкразии.

Не обращая внимания на MSVC, я полагаю, что флаг /arch:SSE2 заставит MSVC использовать инструкции SSE и SSE2 для арифметики одинарной и двойной точности, что должно решить проблему.

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

Если вы используете GCC, ответ SO здесь может помочь:

Если выЕсли вы используете другой компилятор, вы можете найти некоторые подсказки в этом примере (или, возможно, опубликовать комментарий к этому ответу, чтобы узнать, знает ли Майк Динсдейл.

...