В начале этого года я тщательно исследовал эту проблему, так как хотел узнать, возможно ли основать многопользовательскую симуляцию на арифметике с плавающей точкой в .NET.Некоторые из моих выводов могут быть вам полезны:
Можно эмулировать "строгий" режим, вставляя избыточные броски везде , но это кажется хрупким, специфичным для C # и утомительнымрешение.
32-битный JIT испускает инструкции x87, а 64-битный JIT испускает инструкции SSE.Это верно как для Microsoft, так и для Mono.В отличие от x87, плавающая арифметика SSE воспроизводима .
Я считаю, что System.Math просто вызывает эквивалентные функции времени выполнения C, хотя я не смог войти в сборку, чтобы проверить это (есликто-то знает, как это сделать, пожалуйста, проверьте!).Среда выполнения C использует SSE-версии трансцендентных функций, когда это возможно, за исключением нескольких случаев, в частности, sqrt (но написание обертки с помощью встроенных функций для этого тривиально).По самой природе SSE они должны быть воспроизводимыми. Можно программно определить, использует ли среда выполнения C свою реализацию SSE, а не x87 .
Для остальных трансцендентных функций, недоступных в SSE (fmod, sinh, cosh, tanh),возможно, они не вызывают проблем с воспроизводимостью, если на x87 не выполняется дальнейшая операция с их результатом.
Короче говоря, использование 64-битного CLR должно решить проблему арифметики;для трансцендентных функций большинство уже реализовано в SSE, и я даже не уверен, что это необходимо, если вы не выполните арифметику x87 с результатами.