【问题标题】:Why is my program returning a garbage value when k == 0 in the for-loop?为什么我的程序在 for 循环中 k == 0 时返回垃圾值?
【发布时间】:2020-02-17 22:32:17
【问题描述】:

这是一个简单的 C++ 程序,它使用公式计算两个给定数字之间的固定数量值的公式。

在 for 循环中 k = 0 时似乎有一些问题。它正在返回一个垃圾值。

谁能告诉我为什么?

非常感谢任何帮助。提前致谢。

#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.

【问题讨论】:

  • 发生这种情况是因为计算机以二进制数计数。这意味着小的加法和减法可能与预期值略有不同。如果你将它四舍五入或削减从 idk 后面的第五位开始的数字。你应该没事
  • [tangent] l &lt; POINTS, k &lt;= max 不像你想的那样工作。这些比较之一的结果被丢弃。你的意思可能是l &lt; POINTS &amp;&amp; k &lt;= max
  • [专业提示] 不要使用浮点类型作为循环索引。如果你想提高十分之四,那么你可以这样做for (int index = start_value * 10, index &lt; stop_value * 10; index += 4) { divide index by 10 here to get the decimal number }
  • 顺便说一句,std:: 命名空间包含 minmax 名称,从技术上讲,在这种情况下使用它是一个 UB。你很幸运在使用命名空间时不包括&lt;algorithm&gt;(如果任何标题都没有,则没有定义)

标签: c++ for-loop garbage cmath


【解决方案1】:

一个问题问题在于代码(1 / 64) ...因为您已将此表达式放在括号中。因此,它是整数除法,因此总是具有的值。

试试这个吧:

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

您在for 循环中表达“测试”条件的方式也存在问题 - 这里的comma operator 将有效地忽略表达式的第一部分:

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

为安全起见,当您希望测试两个条件时,请使用&amp;&amp; 运算符:

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

最后,您的实际问题:

在 for 循环中 k = 0 时似乎有一些问题。这是 返回一个垃圾值。

不,不是!您对k 变量(即每个循环上的k += increment)执行的浮点运算并不精确:您认为0.4 + (-0.4)实际上'nearly' '0.4' - 'nearly' '0.4';因此,考虑到您使用的数字范围(以及之前循环中累积的“错误”),您获得的值(我的系统给出-5.55112e-16)是对零的“合理近似”。

请随时要求进一步澄清和/或解释。

【讨论】:

  • 哦,非常好。我什至没有注意到循环条件中的逗号,很好。我想说的另一件事是打印k 并让它看起来像他们想要的解决方案(这可能是round())。但这一切对我来说都很好!不错的编辑:)
  • 啊哈!评论作为批评 - 按预期工作!我非常感谢您的意见!
  • @AdrianMole 谢谢你的解释!我在 for 循环中修复了测试条件,并使用了 setprecision(1)
  • @Vaibav79 不,我不认为你错过了任何东西 - 请记住,计算机中的浮点数据只能近似真实世界的值。只是不要尝试使用表单的任何比较,if (k == 0),否则它们可能会失败。
  • 有道理。谢谢!
【解决方案2】:

由于当您增加 0.2 时出现舍入误差,您的 k 值永远不会完全为零——它稍微偏离了一点。见What every computer scientist should know about floating point

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 2013-09-04
    • 1970-01-01
    • 2022-01-22
    相关资源
    最近更新 更多