Цикл не выдает правильный результат

245
06 февраля 2018, 09:32

Всех приветствую, вот код

#include <iostream>
int main()
{
double c = 0.1;
for(double x = c; x < 5;x+=c){
    for(double y = c;y < 5;y += c){
        if((x+y == 5.0)&&(x*x + y*y > 13) ){
            std::cout << "x = " << x << "  y = " << y << std::endl;
            std::cout << x*x*x*x*x + y*y*y*y*y << std::endl;
        }
    }
}
return 0;
}

Этот код ищет пары значений х и у, при которых выполняется условие (x+y == 5.0)&&(x*x + y*y > 13). Если с == 1, то он выдаст значения 1 и 4, что логично и удовлетворяет условию. Если же с == 0.1, то он выдаст х = 0.5, у = 4.5, что также удовлетворяет условию, но он почему-то не выводит значения х = 1 и у = 4, хотя они также вроде как должны попасться при прохождении цикла.

Если же с == 0.01, то он вообще ничего не выводит, хотя должен вывести несколько значений, в которые попадут и значения при с = 0.1 и при с = 1. В общем, не знаю, где моя ошибка в коде. Заранее спасибо.

Answer 1

Поскольку числа с плавающей точкой абсолютно точно представить в двоичном виде нельзя (например, то же значение 0.1 на самом деле хранится как примерно 0.10000000000000000555) - то и сравнение на равенство обычно не срабатывает.

Попробуйте такой код и посмотрите на результаты:

bool equal(double x, double y)
{
    double eps = 1e-10;
    if (x > y + eps) return false;
    if (x < y - eps) return false;
    return true;
}
int main()
{
    double c = 0.1;
    for (double x = c; x < 5; x += c)
    {
        for (double y = c; y < 5; y += c)
        {
            if (equal(x + y, 5.0) && (x * x + y * y > 13))
            {
                std::cout << "x = " << x << "  y = " << y << std::endl;
                std::cout << x* x* x* x* x + y* y* y* y* y << std::endl;
            }
        }
    }
}
Answer 2

Значение 0.1 не представимо точно в двоичной плавающей арифметике на вашей платформе. x в вашем цикле никогда не принимает значение 1, y никогда не принимает значение 4, а x + y никогда не становится равным 5. Потому вы их и не видите.

Либо делайте сравнение с допуском, либо пользуйтесь арифметикой с фиксированной точностью

#include <iostream>
int main()
{
  int c = 1;
  for (int x = c; x < 50; x += c) {
    for (int y = c; y < 50; y += c) {
        if (x + y == 50 && x*x + y*y > 1300) {
            std::cout << "x = " << (double) x / 10 << "  y = " << (double) y / 10 << std::endl;
            std::cout << (double) (x*x*x*x*x + y*y*y*y*y) / 100000 << std::endl;
        }
    }
  }
}
READ ALSO
Как скопилировать с помощью MinGW?

Как скопилировать с помощью MinGW?

Компилирую программу с помощью MinGW таким образом:

214
const = 0 после прототипа функции что означает?

const = 0 после прототипа функции что означает?

в библиотеке qwt, в файле qwt_series_datah, объявлен класс: QwtSeriesData

196
Makefile C++(Linux)

Makefile C++(Linux)

Добрый день возникла проблема с написание Makefile

300
cannot resolve method &#39;findViewById(int)&#39;

cannot resolve method 'findViewById(int)'

Не могу понять в чем ошибка

429