【问题标题】:Combine two bytes in delphi在delphi中合并两个字节
【发布时间】:2016-11-15 19:03:32
【问题描述】:

假设我在Delphi中有两个字节变量:

var 
    b1,b2,result:byte;
begin
    b1:=$05;
    b2:=$04;
    result:=??? // $54
end;

然后我如何将两者结合起来产生一个字节值$54?

【问题讨论】:

  • result:= (b1 shl 4) or (b2 and $0F);

标签: delphi


【解决方案1】:

最简单的方法是

result := b1 * $10 + b2

“高级”方式:

result := b1 shl 4 + b2

【讨论】:

  • 你真的更好地保护 b2 范围 (b2 and $0F); 就像另一位用户在上面的评论中所说的那样!
  • 当然你是对的,但这取决于......我不知道作者从哪里得到这个值,所以我认为它们已经是正确的。在大多数情况下,它们已经是,您无需再添加一项操作。
  • 好吧,如果一个人需要如此多的原始速度以至于一个额外的操作码成为问题,那么他无论如何都不会用 Delphi 编写他的程序。所以“比抱歉更安全”在这里看起来更合适。毕竟我们都使用虚拟方法,它们的调用(与静态方法相比)比单个AND AL, 15 昂贵得多。而且我们都使用 DLLs/BPLs,这也会为每个函数调用带来额外的负担,这比 VMT 查找要轻,但仍然比单个 AND
  • he would not write his program in Delphi anyway - 是的))
  • @Arioch,“比抱歉更安全”不适用于此处,因为我们没有关于所需行为的真正信息。我们得到了一个的例子。有很多方法可以编写函数以使其返回所需的$54,包括琐碎的Result := $54,但也可以是Result := (b2 + 1) shr 4 + (b1 - 1)。没有提问者的意见,你不能争论哪个是正确的。您所能做的就是提及可能的解释并描述它们的不同之处。你提到了可能性,但没有向 Raw 提供任何信息来判断它们的优点。
【解决方案2】:

最好的办法是:

interface

function combine(a,b: integer): integer; inline;  //allows inlining in other units

implementation

function combine(a,b: cardinal): cardinal; inline;
begin
  Assert((a <= $f));
  Assert((b <= $f));
  Result:= a * 16 + b;
end;

由于partial register stalls,使用字节寄存器会降低处理器速度。
断言将在发布模式下被消除。

如果性能很重要,请不要使用除整数(或基数)以外的任何东西。

我不知道为什么人们在谈论 VMT 或 dll。这是一个简单的内联方法,甚至不会生成调用。

【讨论】:

    猜你喜欢
    • 2011-02-23
    • 2012-12-16
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 2022-11-02
    相关资源
    最近更新 更多