Clang-Tidy неправильное округление - PullRequest
1 голос
/ 27 марта 2019

Документация для clang-tidy [bugprone-неправильно-округления] проверка говорит:

Число 0,499999975 (наименьшее представимое число с плавающей точкой ниже 0,5) округляется до 1,0

Насколько я могу определить, наименьшее число с плавающей точкой ниже 0.5 равно 0.4999999702, а не 0.499999975. Но, несмотря на это, оба числа дают мне 0 значения в расчете наивного округления:

#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";
}

Я что-то упустил?

1 Ответ

3 голосов
/ 27 марта 2019

Относительно арифметического преобразования в стандарте:

6.3.1.8 Обычные арифметические преобразования

...

  • В противном случае, еслисоответствующий действительный тип любого из операндов является двойным, другой операнд преобразуется без изменения области типов в тип, соответствующий действительный тип которого является двойным.

  • Значения плавающих операндов ирезультаты плавающих выражений могут быть представлены с большей точностью и в диапазоне, чем требуется для типа;

Итак, в этой строке:

(int)(v1+0.5) 

Ваша переменная v1 повышена до операции с плавающей запятой двойной точности, поэтому вы получаете ноль.

Это должно решить вашу проблему:

#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";
}
...