Arnaud 解释说ord()
返回一个有符号值,这是警告的来源。Arnaud 和 Ken 都建议如何通过避免使用无符号操作数来消除警告。
我想提供另一种意见,并建议您改为选择使用带符号的操作数。假设您仅使用有符号操作数执行计算。考虑以下程序:
{$APPTYPE CONSOLE}
uses
Math;
function CalcPrecision(Radius: cardinal; Active, InProximity: boolean): Cardinal;
begin
Result := Max(50, 100-(3+2*Cardinal(Active and InProximity))*Radius);
end;
begin
Writeln(CalcPrecision(1000, True, True));
Readln;
end.
我相信你会希望这个程序的输出是 50。它不是。输出为 4294962396。
发生的情况是您100-X
在无符号上下文中执行X>100
. 当你这样做时,你有整数溢出,结果是一个非常大的正值。由于您使用的是无符号算术,因此您不能期望这是一个负值,因为无符号中没有负值。
当然,如果启用了溢出检查的编译器选项,您会遇到运行时错误。但即使这样也不是你想要的。获得所需答案的简单方法是使用有符号算术执行操作。
{$APPTYPE CONSOLE}
uses
Math;
function CalcPrecision(Radius: Integer; Active, InProximity: boolean): Integer;
begin
Result := Max(50, 100-(3+2*ord(Active and InProximity))*Radius);
end;
begin
Writeln(CalcPrecision(1000, True, True));
Readln;
end.
这个程序产生了 50 的期望输出。
如果由于某种原因,您需要将值存储回无符号变量,则在计算之外执行此操作。由于上述原因,使用有符号值执行计算很重要。
....
var
Precision: Cardinal;
begin
Precision := CalcPrecision(1000, True, True);
Writeln(Precision);
Readln;
end.
当然,您确实可以提出会溢出计算的输入值,即使它是使用有符号算术编写的。但在实践中你会发现这样的输入是极不可能的。另一方面,使用相当合理的输入数据执行无符号运算时,很容易使您的方程式出错。