gpt4 book ai didi

Delphi:减法时如何避免EIntOverflow下溢?

转载 作者:行者123 更新时间:2023-12-03 14:41:36 25 4
gpt4 key购买 nike

微软已经在 GetTickCount 的文档中表示,您永远无法通过比较滴答计数来检查间隔是否已过去。例如:

不正确(伪代码):

DWORD endTime = GetTickCount + 10000; //10 s from now

...

if (GetTickCount > endTime)
break;

上面的代码很糟糕,因为它很容易发生滴答计数器的翻转。例如,假设时钟接近其范围的末尾:

endTime = 0xfffffe00 + 10000
= 0x00002510; //9,488 decimal

然后执行检查:

if (GetTickCount > endTime)

立即满足,因为 GetTickCount 大于 endTime:

if (0xfffffe01 > 0x00002510)
<小时/>

解决方案

相反,您应该始终减去两个时间间隔:

DWORD startTime = GetTickCount;

...

if (GetTickCount - startTime) > 10000 //if it's been 10 seconds
break;

看同样的数学:

if (GetTickCount - startTime) > 10000

if (0xfffffe01 - 0xfffffe00) > 10000

if (1 > 10000)

这在 C/C++ 中一切都很好,编译器以某种方式运行。

但是德尔福呢?

但是当我在 Delphi 中执行相同的数学运算时,通过溢出检查 ({Q+}, {$OVERFLOWCHECKS ON}),两个刻度计数相减当 TickCount 翻转时生成 EIntOverflow 异常:

if (0x00000100 - 0xffffff00) > 10000

0x00000100 - 0xffffff00 = 0x00000200

此问题的预期解决方案是什么?

编辑:我尝试暂时关闭OVERFLOWCHECKS:

{$OVERFLOWCHECKS OFF}]
delta = GetTickCount - startTime;
{$OVERFLOWCHECKS ON}

但是减法仍然会抛出 EIntOverflow 异常。

是否有更好的解决方案,涉及强制转换和更大的中间变量类型?

<小时/>

更新

我问的另一个问题解释了为什么 {$OVERFLOWCHECKS} 不起作用。它显然只适用于函数级别,而不是级别。因此,虽然以下不起作用有效:

{$OVERFLOWCHECKS OFF}]
delta = GetTickCount - startTime;
{$OVERFLOWCHECKS ON}

以下确实有效:

delta := Subtract(GetTickCount, startTime);

{$OVERFLOWCHECKS OFF}]
function Subtract(const B, A: DWORD): DWORD;
begin
Result := (B - A);
end;
{$OVERFLOWCHECKS ON}

最佳答案

像这样的简单函数怎么样?

function GetElapsedTime(LastTick : Cardinal) : Cardinal;
var CurrentTick : Cardinal;
begin
CurrentTick := GetTickCount;
if CurrentTick >= LastTick then
Result := CurrentTick - LastTick
else
Result := (High(Cardinal) - LastTick) + CurrentTick;
end;

所以你有

StartTime := GetTickCount
...
if GetElapsedTime(StartTime) > 10000 then
...

只要 StartTime 和当前 GetTickCount 之间的时间小于 GetTickCount 臭名昭著的 49.7 天范围,它就会起作用。

关于Delphi:减法时如何避免EIntOverflow下溢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2417919/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com