delphi - 使用Delphi中的十六进制内存值进行常量单

标签 delphi delphi-10-seattle

我如何基于十六进制值制作单个常量,其中该十六进制值为无符号整数和单个常量的原始内存。我想做这样的事情,但它不会编译,这将尝试将十六进制值转换为单个,然后存储该转换的结果,而不是存储十六进制值本身:

LARGEST_SINGLE_LESS_THAN_ZERO = Single($80800000);


我收到“无效的类型转换”错误。

例如:

1的单个值在内存中存储为$ 3F800000。我希望能够创建一个const,使我可以使用$ 3F800000而不是1来设置值。

我也尝试过其他这样的变体,例如:

LARGEST_SINGLE_LESS_THAN_ZERO = PSingle(@$80800000)^;


背景

当提供单个值时,我有一种方法可以用来获取下一个最小的单个值:

type
  PInt32 = ^Int32;

function NextBefore(const aValue: Single): Single;
var
  int32Value: Int32;
begin
  // this function ignores special values nan/inf
  int32Value := PInt32(@aValue)^;
  if (UInt32(int32Value) = $80000000) or (int32Value = 0) then
  begin
    // special handling needed for -0 and 0. We need to go to the smallest
    // negative number.
    int32Value := $80800000;
  end
  else
  begin
    if int32Value >= 0 then
      Dec(int32Value)
    else
      Inc(int32Value);
  end;
  Result := PSingle(@int32Value)^;
end;


这真的很有用,因为我们使用只能执行>或<的向量运算,所以我们用它执行> =和<=的等效项。我们经常对照0进行检查。因此,在需要获取所有数据> = 0的地方,我们将执行以下操作:

MyVector.ThresholdGT(NextBefore(0));


为其他开发人员提供这些操作类型的常量会更好。由于数字不是变量,因此尝试使用下面的PSingle格式将不起作用。

最佳答案

用语言的约束很难做到这一点。也许您能做的最好的事情就是制作一个整数和单个字段都重叠的变量记录类型。

type
  TSingleIntegerVariantRec = record
    case Integer of
      0: (I: Integer);
      1: (S: Single);
  end;


一旦有了可用的类型,就可以使用整型字段声明类型化的常量,然后读取单个字段。

const
  LARGEST_SINGLE_LESS_THAN_ZERO: TSingleIntegerVariantRec = (I: $80800000);
.... 
MyVector.ThresholdGT(LARGEST_SINGLE_LESS_THAN_ZERO.S);


如果要增加一些细微差别,可以对Single实施隐式强制转换运算符,从而可以省略.S。如果使该运算符内联,那么我怀疑发出的代码将非常有效。

这可以满足您的要求,但我不会声称它非常优雅。我们是我,我想将代码使用下一个值向下移动到库函数中,以便您可以传递0并从这些实现细节中屏蔽库的使用者。

换句话说,您将添加一个实现如下的ThresholdGTequal方法:

procedure TMyVector.ThresholdGTequal(const Value: Single);
begin
  ThresholdGT(NextBefore(Value));
end;


然后,此代码的使用者只需编写:

MyVector.ThresholdGTequal(0);


并忽略所有过时的实施细节。

关于delphi - 使用Delphi中的十六进制内存值进行常量单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42709274/

相关文章:

delphi - 如何在调用Web服务期间防止对话框(基本身份验证提示)

delphi - 使用Delphi实现win32应用程序的动态流程图

Delphi:通过 Outlook 发送带有多个附件的电子邮件

delphi - MessageDlg 不发出声音

delphi - 函数初始化代码从西雅图更改为东京吗?

delphi - 如果类型 (Array Variant) 无法将变体转换为类型 (OleStr)

Delphi:如何获取事件变量的地址?

macos - 在 OS X 上运行 Delphi 10 Seattle 应用程序时出现 Dylib 版本错误

delphi - 未找到单元 'CodeSiteLogging'

android - 如何在 Delphi 中禁用显示建议