【问题标题】:Can anyone decipher why these two conversions to unsigned long long give different results?谁能破译为什么这两次转换为 unsigned long long 会产生不同的结果?
【发布时间】:2010-08-09 11:35:07
【问题描述】:
LARGE_INTEGER lpPerformanceCount, lpFrequency;

QueryPerformanceCounter(&lpPerformanceCount);
QueryPerformanceFrequency(&lpFrequency);

(Count.QuadPart 是一个很长的显示 CPU 计数的 long)

(Freq.QuadPart是一秒的Count的长长显示频率)

尝试实时打印微秒。

稳定输出:

printf("%llu\n", ((long double)lpPerformanceCount.QuadPart/ lpFrequency.QuadPart) * 1000000);

不稳定的输出:(结果前后不连贯地跳跃,即使乍一看是正常的)

printf("%llu\n", 1000000 * (lpPerformanceCount.QuadPart / lpFrequency.QuadPart) + (lpPerformanceCount.QuadPart % lpFrequency.QuadPart));

编辑:printf 在其输入中需要进一步(无符号长长)转换,原始代码通过函数的返回值完成。

【问题讨论】:

    标签: c++ c windows winapi


    【解决方案1】:

    你确定%llu 打印一个合理的双倍吗?

    lpPerformanceCount.QuadPart / lpFrequency.QuadPart 给你一个时间,四舍五入到整秒。

    lpPerformanceCount.QuadPart % lpFrequency.QuadPart 为您提供滴答计数(自上一整秒以来的滴答数)。

    为时间添加计数可以让您..如何礼貌地表达...废话。

    我总是使用双重算术,更不用说麻烦了。但是,如果您坚持使用非 FPU 代码,则可以使用:

    count.QuadPart*1000000 / (freq.QuadPart*1000000)
    

    这会更快溢出(尽管我认为这不是一个实际问题)。修复整数算术:

    count.QuadPart / freq.QuadPart 
    + (count.QuadPart % freq.QuadPart) * 1000000 / freq.QuadPart
    

    (我希望是的......)

    【讨论】:

    • 您认为为此目的转换它们最安全的方法是什么? unsigned long long var = ((long double)lpPerformanceCount.QuadPart/ lpFrequency.QuadPart) * 1000000) 是最好的吗? (或 1000000ULL)
    • 我将1.0/freq.QuadPart 存储为每滴答时间,并使用count.QuadPart*timePerTick 一段时间(以秒为单位)。理论上存在精度损失 - 但我从未见过会受到影响的频率值。
    • 我想这对于硬件来说几乎是等价的,因为浮点运算开始发挥作用。感谢您的意见。
    【解决方案2】:

    是的。 IIUC,应该是这样的:

    1000000 * (lpPerformanceCount.QuadPart / lpFrequency.QuadPart) + 
    (lpPerformanceCount.QuadPart % lpFrequency.QuadPart) * 1000000 / lpFrequency.QuadPart
    

    或许

    (lpPerformanceCount.QuadPart / (lpFrequency.QuadPart / 1000000) )
    

    如果lpFreuency.QuadPart 为高,第一个将溢出;如果lpFrequency.QuadPart 较低,则第二个将不准确甚至溢出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 2015-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-04
      相关资源
      最近更新 更多