skip to Main Content

I am trying to figure out how to set ROUND_UP, ROUND_DOWN, ROUND_to_NEAREST, and ROUND_to_INFINITY for an MS Visual Studio project.
The representation of natural numbers should follow the IEEE 754 standards, Which means setting /FP: strict is selected. However, the code is running in an x64 environment.
Through careful selection of rounding mode, I want to cause -0.000000 to be equal to -0.000001, for example.

Cheers
Commodore

I am making come computations and saving the results (tuple). After each operation, I query saved data to know if I had already had the value. (-0.000000,-0.202319) would be equal to (-0.000001,-0.202319) rounding with nearest. How can I do this with Visual Studio?

2

Answers


  1. That’s not how it works. Choosing the rounding mode affects the last bit of the result, that’s it. Comparisons are not affected. And comparisons between 0.000001 and 0.234567 are most definitely not affected.

    What you want cannot be achieved with rounding modes. Feel free to write a function that returns true if two numbers are close together.

    Login or Signup to reply.
  2. In general, == and != for floating-point are not a ‘safe’ method for doing floating-point comparison except in the specific case of ‘binary representation equality’ even using ‘IEEE-754 compliant’ code generation. This is why clang/LLVM for example has the -Wfloat-equal warning.

    Be sure to read What Every Computer Scientist Should Know About Floating-Point Arithmetic. I’d also recommend reading the many great Bruce Dawson blog posts on the topic of floating-point.

    Instead, you should explicitly use an ‘epsilon’ comparison:

    constexpr float c_EPSILON = 0.000001f;
    
    
    if (fabsf(a - b) <= c_EPSILON)
    {
        // A & B are equal within the epsilon value.
    }
    

    In general, you can’t assume that SSE/SSE2-based floating-point math (required for x64) will match legacy x87-based floating-point math, and in many cases you can’t even assume AMD and Intel will always agree even with /fp:strict.

    For example, IEEE-754 doesn’t specify what happens with fast reciprocal operations such as RCP or RSQRT. AMD and Intel give different answers in these cases in the lower bits.

    With all that said, you are intended to use _controlfp or _controlfp_s rather than _control87 to control rounding mode behavior for all platforms. _control87 really only works for 32-bit (x86) platforms when using /arch:IA32.

    Keep in mind that changing the floating-point control word and calling code outside of your control is often problematic. Code assumes the default of "no-exceptions, round-to-nearest" and deviation from that can result in untested/undefined behavior. You can really only change the control word, do your own code, then change it back to the default in any safe way. See this old DirectX article.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search