Home > Software design >  C: How to use decimal number in hex one to one?
C: How to use decimal number in hex one to one?

Time:10-06

I want to "convert" a decimal number to a hex number. Not like 10 -> A.

E.g.: 10 -> 0x10, 55 -> 0x55, 2021 -> 0x2021, ...

My input is an int. I already heard something about it. You can get the first digit with modulo 10. E.g. 55 % 10 is 5. But I don't know how to get the other digits and how to put it together.

CodePudding user response:

I am using this function for other purpose but I did some changes and its work fine. you can use this :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdint.h>
    
    #define CHECK_ALPHA_HEX(REC_CHAR) (unsigned)('@' < REC_CHAR && REC_CHAR < 'G')
    #define CHECK_NUM(REC_CHAR) (unsigned)('/' < REC_CHAR && REC_CHAR < ':')
    
    void DEC_TO_HEX(int in, int *outval ) {
        
        uint8_t tbuff[5];
    
        uint8_t chr_count = 0;
    
        uint8_t len = sprintf(tbuff,"%d",in);
    
        while(chr_count < len) {
                tbuff[chr_count] -= CHECK_NUM(tbuff[chr_count]) ? '0' : CHECK_ALPHA_HEX(tbuff[chr_count]) ? '7' : tbuff[chr_count];
                *outval |= (tbuff[chr_count] << (4 *((len-1) - chr_count)));
                chr_count  ;
        }
    }
    
    int main() {
        
        int out = 0;
    
        int in = 2021;
    
        DEC_TO_HEX(in,&out);`
    
        printf("%x",out);
    }

https://godbolt.org/z/8T9Wqb87n

CodePudding user response:

how to get the other digits

Remove the extracted digit from input.

Repeat the extraction of one digit, until there are no more digits in input.

how to put it together.

Learn C programming language. Write a program that implements the algorithm.


As I understand, an integer value has to be converted to another integer. From there it's just basic arithmetic, where the process generatally consists of:

  • Getting one digit from input.
  • Putting it in output.
  • Removing that digit from input.
  • shifting input & output to desired state

I came up with 3 separate such convert_* function implementations. First one is similar to common simple int->string conversion algorithms - it first converts the digits and that the results is "inverted". The second one extract the digits from propor position from input - getting the most significant base10 digit from input and moving between base10 digits of input. The third one, puts base10 digits on the end of hex number (startign from the mast significant base16 digit), and then shifts hex number to the right to handle 0x55000000 trailing zeros in result.

#include <limits.h>
#include <stdio.h>

const unsigned maxhexdigits = sizeof(unsigned) * CHAR_BIT / 4;

unsigned convert_andrevert(unsigned n) {
    unsigned o = 0;
    unsigned hexdigits = 0;
    // Convert hex digits from "the back"
    while (n && hexdigits != maxhexdigits) {
        o <<= 4;
        o  = n % 10;
        n /= 10;
          hexdigits;
    }
    const unsigned swaps = hexdigits / 2;
    //printf("a %#x %d %d \n", o, hexdigits, swaps);
    // Invert hex digits
    for (unsigned i = 0; i < swaps;   i) {
        const unsigned m1 = 0xFu << (i * 4);
        const unsigned m2 = 0xFu << ((hexdigits - i - 1) * 4);
        const unsigned road = (hexdigits - i * 2 - 1) * 4;
        // extract bits m1
        unsigned t = (o & m1) << road;
        //printf("b o=%#x i=%#x 1=%#x m2=%#x t=%#x road=%d\n", o, i, m1, m2, t, road);
        // set bit m1 in place of m2
        o = (o & ~m1) | ((o & m2) >> road);
        // set bit m2 in place of m1
        o = (o & ~m2) | t;
    }
    return o;
}

unsigned mypow10u(unsigned i) {
    unsigned r = 1;
    while (i--) {
        r *= 10;
    }
    return r;
}

unsigned convert_frommax(unsigned n) {
    n %= mypow10u(maxhexdigits);
    unsigned o = 0;
    // always start from the maximuim digit, because
    // we know it's location.
    for (int i = maxhexdigits - 1; i >= 0; --i) {
        o <<= 4;
        //printf("o=%#x u=%d pow10u(i)=%u digit=%u rest=%u\n",
                //o, i, mypow10u(i),
                //n / mypow10u(i),
                //n % mypow10u(i));
        // extract leading base10 digit
        o  = n / mypow10u(i);
        n %= mypow10u(i);
    }
    return o;
}

unsigned convert_andshift(unsigned n) {
    unsigned o = 0;
    unsigned hexdigits = 0;
    // Convert hex digits from "the back"
    // put put them from the front.
    while (n && hexdigits != maxhexdigits) {
        o >>= 4;
        o  = (n % 10) << (maxhexdigits * 4 - 4);
        //printf("o=%#x %d\n", o, n);
        n /= 10;
          hexdigits;
    }
    // Shift right to handle leading (trailing?) zeros.
    o >>= ((maxhexdigits - hexdigits) * 4);
    return o;
}

void testin(unsigned r, unsigned rr) {
    printf(" -> %#x %s", rr, r == rr ? "OK" : "FAIL");
}

void TEST(unsigned a, unsigned r) {
    printf("%u", a);
    testin(r, convert_andrevert(a));
    testin(r, convert_frommax(a));
    testin(r, convert_andshift(a));
    printf("\n");
}

int main() {
    TEST(1, 0x1);
    TEST(55, 0x55);
    TEST(123, 0x123);
    TEST(2021, 0x2021);
    TEST(12345678, 0x12345678);
}

From basic profiling, convert_andshift is the fastest function.

CodePudding user response:

Here is an approach:

#include<stdio.h>

int main()
{
    int num = 0;
    char cNumHex[20];

    puts("Enter a decimal formed hex number: ");
    scanf("%d",&num);

    sprintf(cNumHex, "0x%d", num);

    printf("\nThe entered as hex: %s\n", cNumHex);

    return 0;
}

The output:

Enter a decimal formed hex number: 
49478

The entered as hex: 0x49478
  •  Tags:  
  • c
  • Related