Member 13844252 Ответов: 3

Почему эта программа не дает правильного квадрата 120? Я новичок.


#include <iostream>
#include <cmath>

using namespace std;

int squarefunction(int x)
{
    return pow(x,2);
}

int main()
{
    cout << squarefunction(120) << endl;
    return 0;
}


Что я уже пробовал:

Вместо того чтобы вернуть 14400 он возвращает 14399

3 Ответов

Рейтинг:
2

Jochen Arndt

То СТД::Пау - cppreference.com[^] функция-это функция с плавающей запятой. Таким образом, первый параметр преобразуется из int к double и double затем результат преобразуется обратно в int при возвращении с вашей функции.

Проблема со значениями с плавающей запятой заключается в том, что большинство чисел не могут быть точно представлены, что приводит к очень малым смещениям к реальному значению. Вот что произошло здесь: double вернулся с работы. pow() функция-это что-то вроде 14399.999999... .

Когда double преобразуется в int, все цифры после десятичной точки игнорируются (отсекаются). Таким образом, вы получите 14399 возвращенных. Распространенным решением, позволяющим избежать этого, является добавление смещения +/- 0,5 при литье в int:

int squarefunction(int x)
{
    // We know that the result is never negative here so that the
    //  sign check (subtracting 0.5 then) can be omitted
    return static_cast<int>(pow(x, 2) + 0.5);
}
Обратите внимание, что я добавил приведение, чтобы избежать предупреждений компилятора о возможной потере точности.


Рейтинг:
2

CPallini

То pow "продвигает" его int аргументы в пользу double единицы, выполняет вычисление и возвращает a double результат. Такой (по своей сути аппроксимированный) double затем результат приводится (усекается) к int внутри вашей функции. Смотрите, например c++ - странный pow(x, y); поведение - переполнение стека[^].


Рейтинг:
1

OriginalGriff

Когда я пробую его, он делает именно то, что я ожидаю, и возвращает 14400, так что он зависит от системы. Вероятно, это преобразование с плавающей запятой в целое число в вашей системе вызывает следующее: pow ожидает работать с double значения не целое число, и возвращает double значение - которое неявно приведено к int чтобы вернуть его из метода. Вероятно, внутренняя форма двойника-это не совсем 14400, а 14399.999999999999999999999999999999999999, который при преобразовании усекается до 14399.
Попробуйте вместо этого:

int squarefunction(int x)
{
    return x * x;
}
И он будет работать на всех системах.