Проблема с отображением значений -nan(ind)

При вводе значения x выводятся некоторые значения y в виде -nan(ind), и также переменная h почему-то равна 0.10000000...01, хотя должна быть равна 0.1.

#include <iostream>
#include <cmath>
#include <clocale>
using namespace std;
int main() {
    setlocale(LC_CTYPE, "");
    double x, y, a, b, n, h;
    double srx = 0, maxx = -10000000;
    cout << "Введите начальное значение a: ";
    cin >> a;
    cout << "Введите конечное значение b: ";
    cin >> b;
    cout << "Введите количество итераций n: ";
    cin >> n;
    h = (b - a)/n;
    for (x = a; x <= b; x = x + h) {
        if ((x >= 2) && (x - sqrt(x)) != 0) {
            y = pow(cos(exp(sqrt(abs(x) - 2)) + pow(x, 3)), 2 * x) - abs(x) / (x - sqrt(x));
            cout << "x = " << x << " y = " << y << endl;
            if (maxx < y) {
                maxx = y;
            }
            srx += y;
        }
        else
            cout << "Значение x = " << x << " не удовлетворяет ОДЗ" << endl;
    }
    if (maxx != 0) {
        cout << "Наибольшее значение функции на интервале [" << a << "," << b << "] равно: " << maxx << endl;
    }
    cout << "Среднее значение функции на интервале [" << a << "," << b << "] равно: " << srx / (n + 1);
}

Ответы (1 шт):

Автор решения: Harry

Давайте допишем еще одну строчку:

    if ((x >= 2) && (x - sqrt(x)) != 0) {
        cout << "cos(exp(sqrt(abs(x)-2))+pow(x,3)) = " << cos(exp(sqrt(abs(x) - 2)) + pow(x, 3)) << endl;
        y = pow(cos(exp(sqrt(abs(x) - 2)) + pow(x, 3)), 2 * x) - abs(x) / (x - sqrt(x));

Мы увидим, что везде, где y == nan, это выражение отрицательно, а возводите вы его в нецелую степень.

И что же такое, скажем, -0.35 в степени 4.2? Как вы себе представляете ответ?

Вот и С++ тоже не представляет, а потому, как написано в описании pow, эту ситуацию обрабатывает так:

Error handling
Errors are reported as specified in math_errhandling.
...
pow(base, exp) returns NaN and raises FE_INVALID if base is finite and negative and exp is finite and non-integer.

Что до второй части вопроса, то, так сказать, добро пожаловать в мир вычислений с плавающей точкой! :)

Здесь нет точного представления, здесь любое число - просто сумма степеней 2 - типа, 2 + 1/2 + 1/16 +...

Так и 0.1 = 1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + ... - словом, бесконечная сумма, которая будет оборвана, чтобы поместить ее в формат double. Отсюда и неточность.

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

→ Ссылка