I have algorithm/computation in Java and unit test for it. The unit test expects result with some precision/delta. Now I ported the algo into .NET and would like to use same uni
I have extensively researched this issue earlier this year as I wanted to know if it was possible to base a multiplayer simulation on floating-point arithmetic in .NET. Some of my findings may be useful to you:
It is possible to emulate "strict" mode by inserting redundant casts everywhere, but this appears to be a brittle, C#-specific and tedious solution.
The 32-bit JIT emits x87 instructions, but the 64-bit JIT emits SSE instructions. This is true both on Microsoft and Mono's implementation. Unlike x87, SSE floating arithmetic is reproducible.
I believe System.Math simply calls the equivalent C runtime functions, although I've been unable to step into the assembly to verify this (if someone knows how to do this, please check!). The C runtime uses SSE versions of transcendental functions when possible, except in a few cases, notably sqrt (but writing a wrapper via instrinsics for that is trivial). By the very nature of SSE these must be reproducible. It is programatically possible to determine whether the C runtime is using its SSE implementation rather than x87.
For the remaining transcendental functions not available in SSE (fmod, sinh, cosh, tanh), it might be that they do not cause reproducibility issues if no further operation is performed on x87 with their result.
So in short, sticking with 64-bit CLR should solve the problem for arithmetic; for transcendental functions, most are implemented in SSE already and I'm not even sure that that's necessary if you don't perform any x87 arithmetic with the results.
Unfortunately there is no way to enforce FP strictness in C#, the .Net CLR just lacks the ability to do calculations with less precision that the maximum that is can.
I think there's a performance gain for this - it doesn't check that you might want less precision. There's also no need - .Net doesn't run in a virtual machine and so doesn't worry about different floating point processors.
However isn't strictfp
optional? Could you execute your Java code without the strictfp
modifier? Then it should pick up the same floating point mechanism as .Net
So instead of forcing .Net to use strictfp
and checking it comes out with the same values as your Java code you could force Java to not use strictfp
and check that it then comes out the same as the .Net code.