Delphi 内联更改了位读取的答案

标签 delphi bit

我正在使用带有默认编译器选项的 Delphi Berlin。我正在做一些位例程,并且有一个情况,内联改变了答案。

我的代码:

function BitGetFromQWord( const AQWord: UInt64; ABitIdx: UInt64 ): Boolean; //inline;
begin
  Assert( ABitIdx<64 );
  Result := ((1 shl ABitIdx) and AQWord)<>0;
end;

procedure TForm22.Button1Click(Sender: TObject);
begin
  ShowMessage( BoolToStr( BitGetFromQWord( $CBBE02D50FD8262F, 31 ), True ) );
end;

procedure TForm22.Button2Click(Sender: TObject);
var
  x: Integer;
begin
  x := 31;
  ShowMessage( BoolToStr( BitGetFromQWord( $CBBE02D50FD8262F, x ), True ) );
end;

对于 Button1Click,添加内联后,答案从 False(看起来正确)更改为 True。我的下表是:

True/False Table

Button2Click 只是用变量替换常量,总是产生 False。

我运行了大量的位检查和设置,并遇到了这个异常。这就是为什么随机十六进制数字在这里的原因。

我在一个较大的项目中还有一个具有相同十六进制数字和位 31 的案例,它根据调试或发布产生不同的结果。尚无法将其简化为合理的示例。

代码看起来正确。我在这里找到了 32 位的类似函数:

Bit Manipulation Using Delphi

所以我的问题是为什么内联词会改变答案?

感谢您的帮助。

最佳答案

您的代码是错误的,因为按位移位是在 32 位上下文中执行的。你必须这样写

Result := ((UInt64(1) shl ABitIdx) and AQWord)<>0;

其中强制转换为 64 位算术。

因此,虽然代码的内联版本与非内联版本的行为不同似乎是错误的,但我怀疑真正的问题是代码的行为定义不明确。一旦你修复了代码,如上所示,你会发现内联和非内联版本的行为相同,并给出正确的答案。

关于Delphi 内联更改了位读取的答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53268687/

相关文章:

delphi - 将 TStreamReader 与 TZDecompressionStream 结合使用时出现 EZDecompressionError

delphi - 在 ImgView32 图层上绘制粗虚线

Delphi 返回字符串的最后 3 个字符

c - 面试-位操作

java - 如何将字节数组中的 37 位更改为现有值的所有补码

delphi - 在 Delphi 应用程序中查看 SolidWorks 工程图

android - (Delphi 10.2) 如何从我的应用程序打开 Android 网络浏览器中的 URL?

将 uint16_t 转换为十进制并将其按位存储在 char 数组中。检索 uint16_t 变量中的数据时出错

c - 在很小的内存中表示非常大的位数组

c - 如何从C中的数字中提取特定位?