Search code examples
c++roundingclang-tidy

Clang-tidy incorrect rounding


The documentation for the clang-tidy [bugprone-incorrect-roundings] check says:

The number 0.499999975 (smallest representable float number below 0.5) rounds to 1.0

As far as I can detect the smallest float number below 0.5 is 0.4999999702, not a 0.499999975. But despite of this, both numbers give me 0 values in naive rounding calculation:

#include <iostream>

int main() {
   
    const float v1 = 0.499999975;
    const float v2 = 0.4999999702;

    std::cout << (int)(v1+0.5) << "\n" 
              << (int)(v2+0.5) << "\n";
}

Am I missing something?


Solution

  • Regarding the arithmetic conversion in the standard:

    6.3.1.8 Usual arithmetic conversions

    ...

    • Otherwise, if the corresponding real type of either operand is double, the other operand is converted, without change of type domain, to a type whose corresponding real type is double.

    • The values of floating operands and of the results of floating expressions may be represented in greater precision and range than that required by the type;

    So in this line:

    (int)(v1+0.5) 
    

    Your v1 variable is promoted to a double precision floating point operation, that's why you get zero.

    This should fix your problem:

    #include <iostream>
    
    int main() {
    
        const float v1 = 0.499999975f;
        const float v2 = 0.4999999702f;
    
        std::cout << (int)(v1 + 0.5f) << "\n" 
                  << (int)(v2 + 0.5f) << "\n";
    }