繁体   English   中英

编译器忽略我在 while(true) 中的 if 语句

[英]Compiler ignores my if statement in while(true)

这是我每 3 秒发送消息 10 次的代码。 但它忽略了 while(true) 中的所有 if 语句

double current;
double freq;
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
QueryPerformanceCounter((LARGE_INTEGER*)&current);
float totalTime = 0.f;
float counter = 0.f;
while (true)
{
    double previous = current;
    QueryPerformanceCounter((LARGE_INTEGER*)&current);
    double deltaTime = (current - previous) / freq;
    totalTime += deltaTime;
    counter += deltaTime;


    if (counter > 3.f)
    {
        cout << "msg Sent" << totalTime << "\n";
        counter = 0;
    }
    if (totalTime > 30.f)
    {
        break;
    }
}

奇怪的是,如果我在中间打印出其中两个值,它就可以正常工作。

double current;
double freq;
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
QueryPerformanceCounter((LARGE_INTEGER*)&current);
float totalTime = 0.f;
float counter = 0.f;
while (true)
{
    double previous = current;
    QueryPerformanceCounter((LARGE_INTEGER*)&current);
    double deltaTime = (current - previous) / freq;
    totalTime += deltaTime;
    counter += deltaTime;

    cout << totalTime << "\n";
    cout << counter << "\n";

    if (counter > 3.f)
    {
        cout << "msg Sent" << totalTime << "\n";
        counter = 0;
    }
    if (totalTime > 30.f)
    {
        break;
    }
}

我认为这是因为编译器优化而发生的。 如果我是对的,有没有办法阻止编译器弄乱我的代码?

LARGE_INTEGER current;
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&current);

float totalTime = 0.f;
float counter = 0.f;
while (true)
{
    LARGE_INTEGER previous = current;
    QueryPerformanceCounter(&current);

    double deltaTime = (current.QuadPart - previous.QuadPart) / static_cast<double>(freq.QuadPart);

    totalTime += deltaTime;
    counter += deltaTime;

    if (counter > 3.f)
    {
        cout << "msg Sent" << totalTime << "\n";
        counter = 0;
    }
    if (totalTime > 30.f)
    {
        break;
    }
}

这次我遵循了 c++ 规则,结果是一样的。 所以这不是铸造的麻烦。 当我把两张照片放在中间时它也可以工作。

问题很可能是由于deltaTime明显小于3.f30.f

因为, if采用分支,否则循环体除了测量时钟之外什么都不做,迭代之间的时间可能非常短。 最初,这不是问题,并且deltaTime将正确添加到countertotalTime 但是,随着这些变量的大小增加,它们最终会变得如此之大,以至于deltaTime将低于double提供的精度。 发生这种情况时,添加deltaTime将停止增加这些变量,因为结果将精确地四舍五入到原始值。

使用float来表示countertotalTime会使情况变得更糟,这是精度最低的浮点类型,这意味着与使用更好的浮点类型相比,在deltaTime的值较大时会出现问题。

通过添加几个std::cout循环体可能会减慢到足以使deltaTime总是足够大以相对于countertotalTime有意义。

不要使用不精确的浮点类型来计算时间,而是尽可能使用 integer 类型来避免这个问题。 根据freq ,您可以计算出多少滴答声相当于您的3.f30.f常数。 然后,您可以只计算刻度并将该计数与计算的限制进行比较。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM