проблема gclib с приведением - PullRequest
0 голосов
/ 04 января 2019

Я узнал об этом при написании тестовой программы. Мне было интересно, где эта проблема находится. Это в C libs (printf), компиляторе clang или процессоре Mac? Я скомпилировал эту программу, используя clang на Mac. Вот короткая программа:

#include <stdio.h>

int main(void) {

    int num = 12;
    double temp = 0.0;

    temp = num/10.0;
    printf("%lf\n", temp);
    temp = temp - 1.0;
    printf("%lf\n", temp);
    temp = temp * 10.0;
    printf("%lf\n", temp);
    int new_num = temp;
    printf("%d\n", new_num);
    int cast_num =(int)temp;
    printf("%d\n", cast_num);

    return 0;
}

Эта программа работает для всех чисел, кроме случаев, когда num заканчивается 12. Когда num заканчивается 12. new_num и cast num = 1, а не 2, как должно. если вы установите num на 22, new_num и cast_num = 2, как и должно быть. Даже работает, как ожидается, если num = 11,10,13,14 и т. Д. ... он не работает, когда num заканчивается в 12. Поэтому установите num = 212 и замените строку 10 на temp = temp-21. и неправильные результаты случаются. Измените число на 213, и оно будет работать как положено.

Кто-нибудь знает природу этой проблемы? Странно, что она появляется только с числом, заканчивающимся на 12.

Есть мысли?

Apple LLVM версия 10.0.0 (clang-1000.10.44.4) Цель: x86_64-apple-darwin18.2.0 Модель резьбы: posix

1 Ответ

0 голосов
/ 04 января 2019

Это из-за проблем с округлением. 2.000000 не всегда 2!

Попробуйте следующее:

temp = temp * 10.0;
printf("%.20lf\n", temp);

и вы, вероятно, заметите, что температура немного ниже 2. Таким образом, приведение к int округляет его до 1.

Проблема в том, что уже 1.2 (12/10.0) нельзя представить точно как число с плавающей запятой, поэтому уже первое деление не точно равно 1,2, но немного меньше. Эта ошибка распространяется вниз до вашего приведения. Чтобы это исправить, округлите математически правильное число с round(), например, перед приведением к int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...