Solved

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

Posted on 2011-02-15
7
522 Views
Last Modified: 2012-05-11
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
0
Comment
Question by:Ed Covney
  • 5
  • 2
7 Comments
 
LVL 32

Expert Comment

by:ewangoya
ID: 34901167
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

0
 
LVL 32

Expert Comment

by:ewangoya
ID: 34901213
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

0
 
LVL 32

Accepted Solution

by:
ewangoya earned 500 total points
ID: 34902039
Here is a better example

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 TForm3.Button1Click(Sender: TObject);
var
  I: Integer;
  BArray: array[0..3] of Byte;
  Value: Cardinal;
  TempStr: string;
begin
  Value := 1247433684;
  for I := 0 to 3 do
    BArray[I] := PByteArray(PCardinal(@Value))[I];

  //display
  for I := 0 to 3 do
    TempStr := TempStr + IntToBinary(BArray[I], 8) +  ' - ' + IntToStr(BArray[I]) + #13#10;
  ShowMessage(TempStr);
end;

Open in new window

0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 32

Expert Comment

by:ewangoya
ID: 34902086
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

0
 
LVL 2

Author Comment

by:Ed Covney
ID: 34902117
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

0
 
LVL 2

Author Closing Comment

by:Ed Covney
ID: 34902148
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 !!
0
 
LVL 32

Expert Comment

by:ewangoya
ID: 34902153

Your welcome
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question