Thread: Converting Hex to Decimal (strtol) not working?

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    14

    Converting Hex to Decimal (strtol) not working?

    Hello,

    I know I am missing something here, can someone tell me how to fix the code below to convert the hex values to a decimal value? At the moment lint1 always equals "0", which is an error;

    Code:
    
    char Posn[4] = {0xff,0xff,0xcf,0x13};
    char outbuffer[] = {Posn[0], Posn[1], Posn[2], Posn[3]};
    long int lint1;
    
    lint1 = strtol (outbuffer, NULL, 0);
    printf("The decimal equivalent is: %ld. \n", lint1);
    
    
    

    Any ideas?

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    strtol converts a string to a long ( as the name tells )

    try something like tis
    Code:
    #include <stdio.h>
    
    int main() {
    	long l = 0;
    	char buff[] = "0xcf13";
    	l = strtol(buff,0,0);
    	printf("%ld\n",l);
    }
    Kurt
    Last edited by ZuK; 05-01-2012 at 05:02 PM.

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    I have an array of individual hex values, which when concatenated, are the actual value. Like this;

    Posn[0] = "0x13"
    Posn[1] = "0xcf"
    Posn[2] = "0xff"
    Posn[3] = "0xff"

    The actual value of I need to convert is "0xPosn[3]Posn[2]Posn[1]Posn[0]", which is equal to "0xffffcf13". I want to programmatically concatenate the value the same way and have the final long int have the value of "-12525".

    How is this done?

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    If you're just trying to convert the machine representation to an integer, then (assuming little-endian byte order) try:
    Code:
        char Posn[4] = {0xff,0xff,0xcf,0x13};
        int n;
        *((char*)&n)   = Posn[3];
        *((char*)&n+1) = Posn[2];
        *((char*)&n+2) = Posn[1];
        *((char*)&n+3) = Posn[0];
        printf("%d\n", n);
    Or switch the byte-order of Posn to make it easier:
    Code:
        char Posn[4] = {0x13,0xcf,0xff,0xff};
        int *n = (int*)Posn;
        printf("%d\n", *n);
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  5. #5
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    That worked, thanks oogabooga!

    How do I then convert my long integer back to a decimal? In this case my n is now equal to "-12525", which is good. I get the value "-125.000", in g, when I do this;



    longdouble g;g = n / 100;


    How do I get "-125.25" in value g?

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    You need to divide by 100.0 instead of 100; for reason read about integer division in C.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  7. #7
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    That worked perfectly, thank you!

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > *((char*)&n) = Posn[3];
    This is just ugly.

    > int *n = (int*)Posn;
    This might just trip up on an alignment exception.

    How about
    Code:
    char Posn[4] = {0xff,0xff,0xcf,0x13};
    int n = 0;
    for ( i = 0 ; i < 4 ; i++ ) {
      n <<= 8;
      n |= Posn[i];
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    I keep forgetting about alignment problems.

    I knew the solution was ugly and that the proper one involved or'ing and shifting but (and I can't remember why) my first attempt didn't work so I posted that crap.

    I think your solution works for either (common) endianness too.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  10. #10
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    Is there a way to do the same data "manipulation" for the individual bits of a value?

  11. #11
    Registered User Maz's Avatar
    Join Date
    Nov 2005
    Location
    Finland
    Posts
    194
    For my eyes loop is not pretty either. What about
    Code:
    char Posn[4] = {0xff,0xff,0xcf,0x13};
    char Posn_be[4] = {0x13,0xcf,0xff,0xff};
    short one=1;
    int n;
    char *tmp=(char *)&one;
    
    if(*tmp)
        n=(int*)Posn;
    else
        n=(int *)Posn_be;

  12. #12
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    Can someone describe what is actually happening at each of these instructions for data manipulation? I would also like to do this for manipulating (read/change) for the individual bits of the data.

  13. #13
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    A union is designed for this purpose.

    This example is taken from "C: The Complete Reference" by Herbert Schildt

    Code:
    union pw {
      short int i;
      char ch[2];
    };
    
    int putw(short int num, FILE *fp)
    {
      union pw word;
    
      word.i = num;
    
      putc(word.ch[0], fp); /* Write first part*/
      return putc(word.ch[1], fp); /*write second part*/
    
    }
    So this should work...
    Code:
    union Posn {
      char ch[4];
      long int lint;
    };

  14. #14
    Registered User Maz's Avatar
    Join Date
    Nov 2005
    Location
    Finland
    Posts
    194
    Quote Originally Posted by 99bobster99 View Post
    Can someone describe what is actually happening at each of these instructions for data manipulation? I would also like to do this for manipulating (read/change) for the individual bits of the data.

    I am not too good with standards, but I will explain you what I've seen in real implementations. I bet others will give specific details about what is required and defined, and what is just assumed and widely used. This is important if you think of doing something guaranteed to work on other but system you know.

    So char is usually 8 bits of data in memory. I assume this is required by standard.
    Integer is often (but not always ? ) 4 bytes of data in memory.

    array of 4 chars which you wrote, really writes 4 bytes of contagious memory. (I am not sure if this alignment is required, but on systems which I have used, the char arrays really have occupied contagious address space).
    eg:
    Code:
    | 255 | 255 | 207 | 19  |
    Now when we take pointer to this char array, we will actually get location of this first item in memory. Start of the array. If we do
    Code:
    int *n=&Posn;
    make pointer to int, and say that this integer starts from same memory location. Thus when we evaluate *n, the 4 bytes written earlier are now interpreted as integer.

    Problem is that there is more than one way to store data. Most common ones are little and big endian architectures. Big endian architecture would store data in a way that normal human mind reads it. Most meaningfull bytes at the start address, and least meaningfull bytes at the left. However x86 and AMD PCs are little endian machines. They store least meaningfull bytes on start address.

    So short int (usually, not required by standard?) is 2 bytes wide. Thus on little endian machine,
    Code:
    short one=1;
    would store data like
    Code:
    | 01 | 00 |
    Now if we do char pointer, place it to point to beginning of short, and then read the first byte, we read
    Code:
    | 01 |
    With big endian architecture
    Code:
    short one=1;
    would be
    Code:
    | 00 | 01 |
    and same char pomter trick would read first byte as
    Code:
    | 00 |
    For bit operations you should use bitwise and/or/shift operations, and possibly bit fields. But using all of these require understanding how the data actually is handled in (virtual) memory.

  15. #15
    Registered User
    Join Date
    Apr 2012
    Posts
    14
    Thank you for the explanation Maz, I understand it fully now!

    Is the same theory used for manipulating the individual bits?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting decimal to binary
    By BrandNewDeipz in forum C Programming
    Replies: 4
    Last Post: 03-03-2012, 09:34 AM
  2. Converting Decimal to Binary
    By BeldenML in forum C Programming
    Replies: 17
    Last Post: 02-09-2012, 11:29 AM
  3. Converting decimal to binary
    By ubernos in forum C Programming
    Replies: 3
    Last Post: 12-06-2005, 10:09 AM
  4. Converting decimal to hex
    By cobrakidd in forum C++ Programming
    Replies: 9
    Last Post: 02-06-2003, 11:37 AM
  5. converting a hex number to decimal???
    By Unregistered in forum Game Programming
    Replies: 8
    Last Post: 04-13-2002, 05:46 PM

Tags for this Thread