Ошибка вычисления компилятора

У меня есть это большое домашнее задание, и я получил неожиданные результаты, я проследил его до следующего кода

for (int i = 0; i < 4; i++)
    cout << (int)((7163 / (int) pow (10, 4 - i - 1))) % 10;

на экране которого появляется 7263, а не 7163! Это не происходит с каждым 4-значным числом, и это сбивает меня с толку, есть ли что-то не так с моей логикой или сумасшедший компилятор. Есть идеи как это исправить?

2 ответа

Проблема здесь не в компиляторе, а в реализации стандартной библиотеки pow функция.

Но это действительно не рекомендуется использовать (int)(pow(n, k)) вычислить nk с двумя целыми числами.

pow не гарантируется точный ответ; это может быть очень маленьким количеством. (На самом деле, его точность вообще не гарантируется, но большинство реализаций будут стараться не ошибаться больше, чем значением младшего бита результата.) (int) усечения, а не округления, даже небольшая ошибка может привести к тому, что результат будет на 1. И в этом случае, если результат pow(10,2) в итоге получается 99,9999999999999, затем преобразование его в целое делает его 99, а 7163/99 - 72.

Так что, если вы настаиваете на использовании powнеобходимо убедиться, что результат округлен, а не усечен (см. round стандартная библиотечная функция). Но было бы лучше придерживаться целочисленной арифметики. Например:

for (int i = 1000; i > 0; i /= 10)
  std::cout << 7163 / i % 10;

Проблема, насколько я понимаю, состоит в том, что результат при i=1 дает "2", когда вы ожидаете "1".

7163 / (10 ^ 2) = 71,63... так что вполне возможно предположить, что вы просто наступаете на ошибку округления. То, как выполняются вычисления значений, будет зависеть от вашей среды, которую вы не указали, однако кажется очевидным, что ваши предположения относительно порядка операций и типов данных неверны.

Тяжелый подход заключается в более строгом приведении типов и определении порядка операций, не оставляя ничего случайного:

cout << ((int) (((int) 7163) / ((int) pow (10, 4 - i - 1)))) % 10;

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

Другие вопросы по тегам