Функция pow () int C ++

0

У меня проблема, когда я пытаюсь умножить целое число 3 pow (67, 1). Он возвращает 200 вместо 201. Вот мой код в C:

int x = 3;
x = x * pow(67, 1);
printf("%d\n", x);

→ 200

Может ли кто-нибудь объяснить мне. Благодарю!

  • 0
    Это 201, когда я компилировал локально.
  • 1
    201 здесь также (VS2013). Какой компилятор / система?
Показать ещё 14 комментариев
Теги:
types

2 ответа

3

pow(67,1) не следует компилировать как C++ 03, но, как отмечает Тони в комментарии, 1 C++ 11 §26.8/11 делает его действительным снова в C++ 11. Visual C++ 12.0 отклоняет код как C++, очевидно, играя по правилам C++ 03. Однако компилятор g++ версии 4.8.2 принимает код. С Visual C++ появляется диагностика о неоднозначном вызове, так как существует много перегрузок.

В C или в C++ 11 аргументы преобразуются в double а pow выполняет возведение в степень. Хотя эти числа могут быть представлены точно как double, операция экспоненции не гарантирует получение точного целого числа. Например, это может быть выполнено как n= e n * ln (a).

Следовательно, результат может быть немного больше или меньше точного 67.

Выражение умножения преобразует целое число 3 в double, точно, и умножение выполняется как double. Если результат pow меньше 67, вы получаете результат, например, 200.9999999..., если он точнее, чем вы получите 201.0, и если он немного больше, вы получите что-то вроде 201.0000001...

Наконец, присваивание обратно x преобразуется обратно в ближайшее значение int, которое в первом случае равно 200, а во втором и третьем случае - 201.

2 Я могу только заключить, что заявленный результат 200 должен (скорее всего) быть неправильным; что он неправильно сообщил.


1) C++ 11 §26.8/11: "Кроме того, должны быть дополнительные перегрузки, достаточные для обеспечения: 1. Если любой аргумент, соответствующий double параметру, имеет тип long double, тогда все аргументы, соответствующие double параметрам, эффективно передаются в long double. 2. В противном случае, если любой аргумент, соответствующий double параметру, имеет тип double или integer, тогда все аргументы, соответствующие double параметрам, эффективно преобразуются в double. 3. В противном случае все аргументы, соответствующие double параметрам, эффективно переводятся в float. ".
2) См. Комментарий к удаленному тексту.
  • 0
    Не правда: 198 невозможно. Умножение также является плавающей точкой, поэтому результат будет похож на 200,9999 или 201,0001 до усечения.
  • 0
    @ david.pfx: ты прав. Благодарю. нет «преобразования в int», о котором я говорил. вероятно, пришло от меня усталость. исправление ...
Показать ещё 4 комментария
3

Предварительное объяснение: функция pow, выполняемая с двойной точностью, не "понимает", что мощность 1 означает "вернуть точное число" и возвращает 66.9999. (Множество 9, но не точно 67). Умножение на 3 дает что-то вроде 200.99997. Наконец, поскольку результат присваивается int, он округляется (усекается) до 200.

  • 0
    Когда я пытаюсь напечатать ("% f", pow (67, 1)), я получил 67.00000003, а не 66.99999. Можете ли вы показать мне, почему?
  • 0
    @ILoveCoding: это на том же ПК, компилятор, настройки оптимизации? Вы также распечатали свой x из вопроса, чтобы узнать, сообщал ли он сейчас 200 или 201?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню