Delphi中 Delphi SetBit函数和TBitRange类型

7ivaypg9  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(143)

我必须在Java中实现下面的 Delphi 函数,但是无论如何,类型TBitRange让我很困惑。在Java中有没有其他替代方法?也许有人可以解释一下这个函数到底是做什么的。

  • 谢谢-谢谢
const 
     BitsPerByte     = 8;
     BitsPerInteger  = SizeOf(Integer) * BitsPerByte;

type
     TBitRange = Byte;

function SetBit(const Value: Integer; const Bit: TBitRange): Integer;
  begin
     Result := Value or (1 shl (Bit mod BitsPerInteger));
  end;

在我的Java中,我实现了这个setBit-function:

static int bitsPerInteger = Integer.SIZE;
    public int setBit(int value, byte bit)
        {
            int result = value | (1 << (bit % bitsPerInteger));
            return result;
        }

如果我没理解错的话,这个函数会返回一个值的副本,该值的位在 bit 位置。bitsPerInteger 变量是 Integer.SIZE,等于32。为了测试,我创建了两个变量:字节位= 0x 34;它等于整数52,int值= 4;.指令位% bitsPerInteger;在这种情况下为20和价值|(1〈〈(bits % bitsPerInteger))将值的第20位设置为1,那么它等于1048576。所以我把这两个变量作为参数传递,然后得到1048576。是这样吗?
为什么需要将 Byte 类型的变量作为位位置参数,然后通过 mod 运算得到参数 value 在位字符串中的实际位位置?我们不能用整数来指示 value 中的位位置吗?

1szpjjfi

1szpjjfi1#

理想情况下,TBitRange应为子范围,例如:

type
  TBitRange = 0..31;

子范围会在编译时期胁迫执行。
Java没有子范围,因此没有对等项。
您可以按如下方式声明函数:

public static int SetBit(final int Value, final byte Bit)
{
    assert bit >= 0;
    assert bit <= 31;   
    final int shift = 1 << Bit;
    return Value | shift;
}

遗憾的是,仅在运行时检查Assert。
但是,在您之前删除的问题中,您将TBitRange定义为:

type
  TBitRange = Byte;

Java中的byte类型是带符号的,而 Delphi 中的byte类型是无符号的。Java中没有无符号的8位int。对于这个问题来说,带符号的Java字节就可以了。
"关于她"
Delphi 的shl/shr遵循x86语义,因此在整数的32处被环绕。因此,mod BitsPerInteger部分是无意义的。该语言已经按照其规范执行了此操作(即someint shl 32是空操作)。
Java做同样的事情,所以在Java中也不需要mod。

此函数的确切作用是什么?

就像标签上写的那样:它设置位。
整数是32位类型。
这意味着变量中有32位(开/关开关,也称为布尔值)。
这些编号从0到31。
如果你想节省空间,你可以使用这个事实在一个整数中存储32个布尔值,而不是必须使用32个变量。缩减8倍。
在 Delphi 中,我们通常使用set of ...来实现这一点。Java没有集合,所以你必须求助于使用位域来代替。
位域实际上是一个压缩的array of boolean,但是因为位域没有数组语法,所以你必须使用函数来代替。

BoolArray[8]:= true -> BitField:= SetBit(BitField,8);
if BoolArray[8] then ... -> if GetBit(BitField,8) then ...

显然,在 Delphi 中,您可以使用属性来模拟这一点:

TBitField = record
private
  FStorage: integer;
  function GetBit(Index: TBitRange): boolean;
  procedure SetBit(Index: TBitRange; const Value: boolean);
public
  property IsTrue[Index: TBitRange]: boolean read GetBit write SetBit;
end;

Properties是Java所不具备的另一项功能,因此在Java中,实际上不可能实现这种伪数组技巧。

ikfrs5lh

ikfrs5lh2#

由于mod操作是冗余的,并且SHL是x86语义:

function SetBitSimple(const Value: Integer; i: byte): Integer;
begin
  Result:= Value OR (1 shl i);
end;

(152,12)));
00000000000000000001000010011000

相关问题