Jump to content
o815

UInt64 -> TArray<Byte> -> shift bits

Recommended Posts

Hey there,

 

following problem:

 

I used a UINT64 to represent bitewise data. So with UINT64 I have 64 bits. The problem is now, I need more than 64bits to represent my data.

 

So I converted my UINT64 to an TArray<Byte>.

Because it's a dynamic array I can represent 64Bits with array lenght = 8.

So far so good, everything is working as expected, I can also use logical operators "AND", "OR" etc... bytewise.

 

There is only one problem which I am not 100% sure how to solve it:

 

With UINT64 and (JclLogic - JEDI Library) I was also able to shift my UINT64 "shl" / "shr".

Someone has an idea how to shift bitwise in an TArray<Byte> ?

 

My current idea is to first shift my array bytewise (if bitshift > 8Bits f.e.) and in second iteration I shift my bytes bitwise.

Someone has another / better idea how to solve this?

 

// Note: Self => Array to shift -> TArray<Byte>
function shiftLEFT(ACount : Integer): TArray<Byte>;
var
  idx    : integer;
  buffer : Word;
  bytes  : integer;
  bits   : integer;
  cnt    : integer;

begin
  Setlength(result, Length(Self));
  bytes  := trunc(ACount/8);
  bits   := Acount mod 8;

  SetLength(result, length(Self) + bytes);

  FillChar(result[0], length(result),0);
  // shift bytes
  CopyMemory(@result[bytes], @Self[0], length(Self));

  cnt := length(result);

  // shift bits
  for idx := cnt-1 downto 0 do
  begin
    buffer := result[idx] shl bits;

    if(buffer > $FF) then
    begin
      // MSB BYTE
      if(idx = length(result)-1) then
      begin
        SetLength(result, cnt+1);

        result[cnt]     :=  (buffer shr 8) and $FF;
        result[idx]     :=  (buffer      ) and $FF;
      end else
      begin
        result[idx + 1] := ((buffer shr 8) and $FF) or result[idx + 1];
        result[idx    ] :=  (buffer      ) and $FF;
      end;
    end else
    begin
      result[idx] := (buffer) and $FF;
    end;
  end;
end;

 

 

Edited by o815

Share this post


Link to post

@o815

im not specialist in bitwise usage, but if a "set of bytes" is a real -UInt64, then, you can catch all "bytes" that represent your real-UInt64 and convert to UInt64, do the calculating, and re-convert to bytes again.. can you get it?

another, if you need "arrays of bytes", then you can have "array of UInt64" not?  xx :TArray<UInt64>;

another another:  dinamic Array is "var" param no? then, maybe you dont need "result := ....XXX modified"  -> Delphi dynamic arrays are always reference-types.

 

14 minutes ago, o815 said:

shiftLEFT(AData : TArray<Byte>;   -->> (var AData:TArray<UInt64>.... )

Edited by programmerdelphi2k

Share this post


Link to post
// fixed...
type
  TADyn   = array of integer;
  TAClose = array [0 .. 1] of integer;

procedure TForm1.Button1Click(Sender: TObject);
var
  ADyn  : TADyn;
  AClose: TAClose;
  AOpen : array of integer;
  // -------------------
  procedure ShowMeArrayOpen(Arr: array of integer);
  begin
    Arr[0] := 123456;
    ShowMessage(AOpen[0].ToString);
  end;

  procedure ShowMeArrayDyn(Arr: TADyn);
  begin
    Arr[0] := 123456;
    ShowMessage(ADyn[0].ToString);
  end;

  procedure ShowMeArrayClose(Arr: TAClose);
  begin
    Arr[0] := 123456;
    ShowMessage(AClose[0].ToString);
  end;

begin
  AOpen := AOpen + [111];
  ShowMeArrayOpen(AOpen);
  ShowMessage(AOpen[0].ToString);
  //
  ADyn := ADyn + [333];
  ShowMeArrayDyn(ADyn);
  ShowMessage(ADyn[0].ToString);
  //
  AClose[0] := 444;
  ShowMeArrayClose(AClose);
  ShowMessage(AClose[0].ToString);
end;

source: old Rudy article: http://rvelthuis.de/articles/articles-openarr.html   as he said: it's confused but...

Edited by programmerdelphi2k

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×