LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-22-2004, 08:31 AM   #1
appas
Member
 
Registered: Jul 2004
Posts: 72

Rep: Reputation: 15
how to convert long integer value to byte array


Hi all,

I need to convert to a long inetger value to byte array in c so that i can access the four byte value of
long integer separately.Could anyone please suggest me a way of doing this.
I would like to elaborate the problem,

long int testval = 3840 ;

The binary value of the above long value (3840)is

0000 0000 // first byte
0000 0000 // second byte
0000 1111 //third byte
0000 0000 // fourth byte

What i need is a way to get the byte values separately and store in char [4] in c, so that
char[0] = 0000 0000 // first byte
char [1] = 0000 0000 // second byte
char [2] = 0000 1111 //third byte
char [3] = 0000 0000 //fourth byte
Could someone help me to solve this.
Thanks for your time,

Last edited by appas; 11-22-2004 at 08:39 AM.
 
Old 11-22-2004, 09:08 AM   #2
Nerox
Member
 
Registered: Jul 2004
Location: Spain
Posts: 111

Rep: Reputation: 20
Take a look at this code:
Code:
#include <stdio.h>

main(){
unsigned long int x = 4194967296;
unsigned int a = x % 256;
unsigned int b = x % 65536 - a;
unsigned int c = x % 16777216 - (a + b) ;
unsigned int d = x % 4294967296 - (a + b + c);
printf("First byte:\t%u\n",a);
printf("Second byte:\t%u\n",b);
printf("Third byte:\t%u\n",c);
printf("Fourth byte:\t%u\n",d);
}
You must use the % operator in order to 'select' a determined length of bits.

I hope it helps.
 
Old 11-22-2004, 09:17 AM   #3
appas
Member
 
Registered: Jul 2004
Posts: 72

Original Poster
Rep: Reputation: 15
Thanks for your reply, Nerox.
i have one more question whether the same code with negative long values.
Thanks once again.
 
Old 11-22-2004, 09:44 AM   #4
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 59
Well, keep in mind that this very strongly depends on the endianness of the computer you're running this on:

Code:
#include <stdio.h>

int main(void)
{
  long int testval = 3840;
  unsigned char ch[4];

  ch[0] = testval & 0xFF;
  ch[1] = (testval & 0xFF00) >> 8;
  ch[2] = (testval & 0xFF0000) >> 16;
  ch[3] = (testval & 0xFF000000) >> 24;

  printf("First byte:  %d\n", ch[0]);
  printf("Second byte: %d\n", ch[1]);
  printf("Third byte:  %d\n", ch[2]);
  printf("Fourth byte: %d\n", ch[3]);

  return 0;
}
itsme@itsme:~/C$ ./split
First byte:  0
Second byte: 15
Third byte:  0
Fourth byte: 0
This is called masking. Say you've got this binary number 10011100. You want to cut it up into 4 pieces. You can use the masks 00000011, 00001100, 00110000, and 11000000. If you did 1001100 & 00110000 you'd get 00010000, but then you have to shift the bits to the right 4 times to get 00000001.
 
Old 11-22-2004, 12:06 PM   #5
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Actually, Itsme86's method doesn't rely too much on endianness. The following method WOULD strongly rely on the endianness of the machine, though...

Code:
long int blah = 3840;
char* pBlah = (char*)&blah;

printf("%d\n", pBlah [0]);
printf("%d\n", pBlah [1]);
printf("%d\n", pBlah [2]);
printf("%d\n", pBlah [3]);
Note that on a little endian machine the last thing printed above would be the most significant byte, but on a big endian machine, the last thing printed would be the least significant byte.

Using itsme86's method, you avoid having to know about the endianness because you are not directly accessing the way the integer is stored. (3840 & 0xFF00) >> 8 is going to be the same no matter if it's stored as big or little endian...

Last edited by deiussum; 11-22-2004 at 12:10 PM.
 
Old 11-22-2004, 12:07 PM   #6
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 59
True. Thanks for pointing that out
 
Old 11-22-2004, 09:35 PM   #7
appas
Member
 
Registered: Jul 2004
Posts: 72

Original Poster
Rep: Reputation: 15
Thanks for the replies, I will try out and get back if furthur clarifications is needed.
 
Old 11-23-2004, 10:08 AM   #8
Nerox
Member
 
Registered: Jul 2004
Location: Spain
Posts: 111

Rep: Reputation: 20
I think my code is also independent from Endianness because i think it prints the same value on both architectures. Am i wrong?

TIA
 
Old 11-23-2004, 10:16 AM   #9
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Nope, you're right. You didn't claim yours was dependent on the endianness, though. Also, generally when doing this type of stuff, I tend to think of it in terms of bitmasks the way itsme86 showed rather than in terms of using the modulus as you did in your example... It doesn't make your way any less relevent, though.

Actually, after looking at it closer, your method isn't quite right. You still need to do a bit shift on them. (Or to go more along with the spirit of using the modulus, the appropriate division...)

Just to recap, here's a program that uses all 3 methods... they all print the same thing on a little endian machine, but on a big endian machine the last method will have the bytes in the reverse order.

Code:
#include <stdio.h>

main()
{
    unsigned long int x = 4194967296;
    unsigned int a = x % 256;
    unsigned int b = (x % 65536 - a)/256;
    unsigned int c = (x % 16777216 - (a + b))/65536;
    unsigned int d = (x % 4294967296 - (a + b + c))/16777216;
    unsigned char* pX = &x;

    printf("First byte:\t0x%.2x\n",a);
    printf("Second byte:\t0x%.2x\n",b);
    printf("Third byte:\t0x%.2x\n",c);
    printf("Fourth byte:\t0x%.2x\n",d);
    printf("=====================\n");
    printf("First byte:\t0x%.2x\n", x & 0xFF);
    printf("Second byte:\t0x%.2x\n", (x & 0xFF00) >> 8);
    printf("Third byte:\t0x%.2x\n", (x & 0xFF0000) >> 16);
    printf("Fourth byte:\t0x%.2x\n", (x & 0xFF000000) >> 24);
    printf("=====================\n");
    printf("First byte:\t0x%.2x\n", pX[0]);
    printf("Second byte:\t0x%.2x\n", pX[1]);
    printf("Third byte:\t0x%.2x\n", pX[2]);
    printf("Fourth byte:\t0x%.2x\n", pX[3]);
}
Results:
Code:
First byte:     0x00
Second byte:    0x1f
Third byte:     0x0a
Fourth byte:    0xfa
=====================
First byte:     0x00
Second byte:    0x1f
Third byte:     0x0a
Fourth byte:    0xfa
=====================
First byte:     0x00
Second byte:    0x1f
Third byte:     0x0a
Fourth byte:    0xfa

Last edited by deiussum; 11-23-2004 at 10:32 AM.
 
Old 11-23-2004, 10:33 AM   #10
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 59
Here's another way to do it that I don't think is even guaranteed to work by the standard:
Code:
itsme@itsme:~/C$ cat split2.c
#include <stdio.h>

int main(void)
{
  union
  {
    long int num;
    char ch[4];
  } data;

  data.num = 3840;

  printf("First byte:  %d\n", data.ch[0]);
  printf("Second byte: %d\n", data.ch[1]);
  printf("Third byte:  %d\n", data.ch[2]);
  printf("Fourth byte: %d\n", data.ch[3]);

  return 0;
}
itsme@itsme:~/C$ ./split2
First byte:  0
Second byte: 15
Third byte:  0
Fourth byte: 0
 
Old 11-23-2004, 10:40 AM   #11
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
I should also note that this is with a 32-bit compiler on an 32-bit architecture... a 64-bit compiler on a 64-bit architecture would likely define a long int as 64 bits instead of 32, so in that case, the method of casting to a char* or using a union as in the latest example would likely be grabbing the bytes from the wrong spot anyway....
 
Old 11-23-2004, 01:56 PM   #12
Nerox
Member
 
Registered: Jul 2004
Location: Spain
Posts: 111

Rep: Reputation: 20
Thank you deiussum and thank you itsme86. Now i understand why my program wasn't good enough. My old program didn't calculate each byte value really.

Thank you ever so much.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C how to convert an integer to string? totti10 Programming 10 11-10-2005 05:49 AM
Convert Integer to Char gjagadish Programming 5 10-14-2005 10:09 AM
integer encoding & byte ordering slzckboy Programming 25 07-09-2005 04:40 PM
Java byte array problem Mohsen Programming 2 03-11-2004 01:37 PM
c: array of poiners(integer or double) jetfreggel Programming 3 12-29-2002 08:39 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:41 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration