cout 语句如何影响所写代码的 O/P

How does the cout statement affect the O/P of the code written?

本文关键字:代码 语句 何影响 影响 cout      更新时间:2023-10-16
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
    int t;
    double n;
    cin>>t;
    while(t--)
    {
        cin>>n;
        double x;
        for(int i=1;i<=10000;i++)
        {
            x=n*i;
            if(x==ceilf(x))
            {
                cout<<i<<endl;
                break;
            }
        }
    }
    return 0;
}

对于 I/P:

352.983.16
操作

/操作:

1

如果我的代码是:

#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
    int t;
    double n;
    cin>>t;
    while(t--)
    {
        cin>>n;
        double x;
        for(int i=1;i<=10000;i++)
        {
            x=n*i;
            cout<<"";//only this statement is added;
            if(x==ceilf(x))
            {
                cout<<i<<endl;
                break;
            }
        }
    }
    return 0;
}

对于相同的输入,O/P 为:

15025

第二个代码中唯一添加的额外行是:cout<<"";

任何人都可以帮助找出为什么仅仅因为第二个代码中添加的 cout 语句而产生如此大的差异吗?

嗯,

这是一个名副其实的海森虫。我试图将您的代码简化为一个最小的复制示例,最终得到这个 (http://ideone.com/mFgs0S):

#include <iostream>
#include <math.h>
using namespace std;
int main()
{
    float n;
    cin >> n;  // this input is needed to reproduce, but the value doesn't matter
    n = 2.98;  // overwrite the input value
    cout << "";  // comment this out => y = z = 149
    float x = n * 50;   // 149
    float y = ceilf(x); // 150
    cout << "";  // comment this out => y = z = 150
    float z = ceilf(x); // 149
    cout << "x:" << x << " y:" << y << " z:" << z << endl;
}

ceilf的行为似乎取决于围绕它发生的iostream操作的特定顺序。不幸的是,我目前没有办法更详细地调试,但也许这将有助于其他人弄清楚发生了什么。无论如何,几乎可以肯定这是 gcc-4.9.2 和 gcc-5.1 中的一个错误。(您可以在 ideone 上检查您是否在 gcc-4.3.2 中没有这种行为。

你可能会遇到浮点表示的问题 - 也就是说,计算机不能完美地表示所有分数。因此,当您看到 50 时,结果可能更接近 50.00000000001。这是您在处理doublefloat时会遇到的一个非常常见的问题。

处理它的一种常见方法是定义一个非常小的常数(在数学术语中,这是 Epsilon,一个"足够小"的数字)

const double EPSILON = 0.000000001;

然后你的比较将从

if (x==ceilf(x))

到类似的东西

double difference = fabs(x - ceilf(x));
if (difference < EPSILON)

这将消除双打中的那些微小的不准确之处。

"比较平等浮点数学并不精确。像 0.2 这样的简单值无法使用二进制浮点数精确表示,并且浮点数的有限精度意味着运算顺序的微小变化可能会改变结果。不同的编译器和 CPU 体系结构以不同的精度存储临时结果,因此结果会因环境的详细信息而异。如果您进行计算,然后将结果与某些预期值进行比较,则极不可能得到预期的结果。

换句话说,如果您进行计算,然后进行此比较:如果(结果 == 预期结果)

那么比较不太可能是真的。如果比较为真,那么它可能不稳定 - 输入值,编译器或CPU的微小变化可能会改变结果并使比较为假。

从 http://www.cygnus-software.com/papers/comparingfloats/Comparing%20floating%20point%20numbers.htm

希望这能回答你的问题。

你也有问题

if(x==ceilf(x))

ceilf() 返回一个浮点值和你声明为双精度值的 x。参考浮点比较中的问题,了解为什么这不起作用。

将 x 更改为浮动,程序运行正常,

我在笔记本电脑甚至在线编译器上进行了简单的尝试。
G++(4.9.2-10)给出了所需的输出(3个输出),以及 geeksforgeeks.org 的在线编译器。然而,ideone,codechef并没有给出正确的输出。
我只能推断在线编译器将他们的编译器命名为"C++(gcc)"并给出错误的输出。而 geeksforgeeks.org,它将编译器命名为"C++",与 g++(在 Linux 上测试)一起完美运行。
因此,我们可以得出一个假设,即他们使用 gcc 编译C++代码作为此链接中建议的方法。:)