Почему моя программа возвращает значение мусора, когда k == 0 в for-l oop? - PullRequest
1 голос
/ 18 февраля 2020

Это простая программа на C ++, которая вычисляет f (x), используя формулу для фиксированного числа значений между двумя заданными числами.

Кажется, что есть некоторая проблема, когда k = 0 в for l oop. Он возвращает мусорное значение.

Может кто-нибудь сказать мне, почему?

Любая помощь высоко ценится. Заранее спасибо.

#include<iostream>
#include<iomanip>
#include<cmath>

using namespace std;

int main ()
{

  int const POINTS = 21;
  double const PI = 3.1416;
  double min, max, increment, dataPoints[21];

  cout << "Enter max value: ";
  cin >> max;

  cout << "Enter min value: ";
  cin >> min;

  increment = (max - min) / (POINTS - 1);


  cout << setw (20) << "X-Value" << "|";
  cout << setw (20) << "Y-Value" << endl;

  double k;
  int l;

  for (k = min, l = 0; l < POINTS, k <= max; l++, k += increment)
    {
      dataPoints[l] = (PI / 16) * sin (6.036 * k) + (1 / 64) * PI * cos (24.44 * k);
      cout << setw (20) << k << setw (20) << dataPoints[l] << endl;
    }

}

Вывод:

Enter max value: 4
Enter min value: -4
             X-Value|             Y-Value
                  -4            0.164018
                -3.6          -0.0507715
                -3.2          -0.0881608
                -2.8            0.182492
                -2.4           -0.184497
                  -2           0.0931637
                -1.6           0.0453027
                -1.2            -0.16085
                -0.8            0.195021
                -0.4           -0.130529
       -5.55112e-016       -6.57901e-016
                 0.4            0.130529
                 0.8           -0.195021
                 1.2             0.16085
                 1.6          -0.0453027
                   2          -0.0931637
                 2.4            0.184497
                 2.8           -0.182492
                 3.2           0.0881608
                 3.6           0.0507715
                   4           -0.164018

Process returned 0 (0x0)   execution time : 3.634 s
Press any key to continue.

Ответы [ 2 ]

3 голосов
/ 18 февраля 2020

Одна проблема заключается в коде (1 / 64) ... потому что вы поместили это выражение в скобки. Таким образом, это целое деление и, как таковое, всегда будет иметь значение ноль .

Попробуйте вместо этого:

    dataPoints[l] = (PI / 16) * sin (6.036 * k) + (1.0 / 64) * PI * cos (24.44 * k);

Существует также проблема в том, как вы выразили условие 'test' в своем for l oop - оператор запятой здесь будет эффективно игнорировать первая часть выражения:

for (k = min, l = 0; l < POINTS, k <= max; l++, k += increment)

В целях безопасности, когда вы хотите проверить оба условия, используйте оператор &&:

for (k = min, l = 0; l < POINTS && k <= max; l++, k += increment) {

Наконец Ваш актуальный вопрос:

Кажется, есть некоторая проблема, когда k = 0 в для l oop. Он возвращает значение мусора.

Нет, это не так! Операции с плавающей запятой, которые вы выполняете с переменной k (т. Е. k += increment, для каждого l oop), не точны: то, что вы думаете, будет 0.4 + (-0.4), будет на самом деле будет 'nearly' '0.4' - 'nearly' '0.4' ; таким образом, значение, которое вы получаете (моя система дает -5.55112e-16), является «разумным приближением» к нулю, учитывая диапазоны чисел, которые вы использовали (и накопленные «ошибки» в предыдущих циклах).

Не стесняйтесь просить дальнейших разъяснений и / или объяснений.

2 голосов
/ 18 февраля 2020

Из-за ошибки округления при увеличении на 0,2 ваше значение k никогда не становится равным точно нулю - его значение немного уменьшается. См. Что должен знать каждый компьютерщик о плавающей точке

...