Link to home
Start Free TrialLog in
Avatar of Ed Covney
Ed CovneyFlag for United States of America

asked on

If there a quick way to convert a cardinal value into 4, 8-bit bytes?

I would like to be able to break apart, unsigned 32-bit integer values into 4 "byte" values of 8-bits each. (For best viewing please paste below into notepad and use courier new font).

Example: cardinal value is:  

    0 1 0 0 1 0 1 0   0 1 0 1 1 0 1 0   0 1 0 1 0 0 1 1   1 1 0 1 0 1 0 0    (1247433684 dec)

and I like to break it apart into 4 8-bit bytes:

    0 1 0 0 1 0 1 0  ( 74)
    0 1 0 1 1 0 1 0  ( 90)
    0 1 0 1 0 0 1 1  ( 83)
    1 1 0 1 0 1 0 0  (212)

I will ask a follow-on question to re-combine the 4 bytes into 1 cardinal value the most direct way (without multipying?).

TIA,  Ed
Avatar of Ephraim Wangoya
Ephraim Wangoya
Flag of United States of America image

type cast to ByteArray


var
  X: cardinal;
  I, J: Byte;
begin
  X := 1247433684;
  I := PByteArray(PCardinal(@X))[0];
  J := PByteArray(PCardinal(@X))[1]; 
  ShowMessage(IntToStr(I) + '   ' + IntToStr(I) );

Open in new window

You can add IntToBinary function
function IntToBinary(Int: Integer; Digits: Byte): string;
const
  CONVERT:array[0..1] of Char = '01';
var
  cnt: Integer;
begin
  SetLength(Result, Digits);
  for cnt := Digits downto 1 do
  begin
    Result[cnt] := CONVERT[Abs(Int) mod 2];
    Int := Int shr 1;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  X: cardinal;
  I: Byte;
begin
  X := 1247433684;
  I := PByteArray(PCardinal(@X))[0];
  ShowMessage(IntToBinary(I, 8));
end;

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Ephraim Wangoya
Ephraim Wangoya
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
To convert the bytes back to cardinal, just do the reverse
procedure TForm3.Button2Click(Sender: TObject);
var
  BArray: array[0..3] of Byte;
  Value: Cardinal;
begin
  BArray[0] := 212;
  BArray[1] := 83;
  BArray[2] := 90;
  BArray[3] := 74;

  Value := PCardinal(PByteArray(@BArray[0]))^;
  ShowMessage(IntToStr(Value));
end;

Open in new window

Avatar of Ed Covney

ASKER

wow, wow, wow.
Other the begin and end, I don't understand one line of your function code, but it works and works so darn well, I just can't believe what I'm seeing here.  I had to do 1,000,000,000 iterations before I noticed about a 3 second pause. That's over 1,000,000,000 conversions per second. And I'm using a 2.6 GHz PC, not exactly the fastest on the block . . . or even in the room!!!

ewangoya - I just can't thank you enough. Thank you, thank you, thank you . . . . .

Ed

var
  X: cardinal;
  I, J, K, L: Byte;
begin
  X := 1247433524;
  for x := 0147433524 to 1247433524 do begin
     I := PByteArray(PCardinal(@X))[0];
     J := PByteArray(PCardinal(@X))[1];
     K := PByteArray(PCardinal(@X))[2];
     L := PByteArray(PCardinal(@X))[3];
  end;
  ShowMessage(IntToBinary(I,8)+#13#10+IntToBinary(J,8)+#13#10+IntToBinary(K,8)+#13#10+IntToBinary(L,8) );
  ShowMessage(IntToStr(I)+IntToStr(J)+IntToStr(K)+IntToStr(L) );
  ShowMessage(Chr(I)+Chr(J)+Chr(K)+Chr(L) );

Open in new window

The solution involved Assembler, which I'll never understand but I will ALWAYS appreciate. Without it, my code would be an order of magnitude (or more) slower.

EWANGOYA rocks !!

Your welcome