eepty
eepty

Reputation: 746

How to convert a 5-bytes hex number to 10base number and represent it in C-type string?

I have a hex number which consist of 5 bytes: 0xEEDDCCBBAA. This number is stored in an array: [0xEE 0xDD, 0xCC, 0xBB, 0xAA]. I want to convert it to 10base decimal number and represent it as a C-type string: "1025923398570". (0xEEDDCCBBAA is equal to 1,025,923,398,570)

One problem is my system only supports max. 32-bits type variable, so I cannot have a single variable to store this number or perform any type of operation larger than 32-bits. For example I cannot do:

unsigned long long val = 0xeeddccbbaa;
unsigned char buf[50];
sprintf(buf, "%d", val);

Thank you very much.

Edit: As my question seems confusing so I wrote it again.

Upvotes: 1

Views: 1373

Answers (4)

user1196549
user1196549

Reputation:

The real challenge here is the conversion to base 10, using 32 bits arithmetic only.

Let your 64 bits number be N = M.2^32 + L, and use the decomposition X = 10 (X/10) + (X%10) = 10 Xq + Xr.

Then,

N = (10.Mq + Mr)(10.429496729 + 6) + (10.Lq + Lr) = 100.429496729.Mq + 10.6.Mq + 10.429496729.Mr + 6.Mr + 10.Lq + Lr.

From this we derive the unit digit

Nr = N%10 = (6.Mr + Lr) % 10,

and the quotient

Nq = N/10 = 10.429496729.Mq + 6.Mq + 429496729.Mr + Lq + (6.Mr + Lr) / 10.

In the latter expression, the first two terms are just Mq.2^32, so you divide the most significant doubleword by 10. The next term will fit in 32 bits as Mr is at most 9 and 429496729.9 is less than 2^32. I don't think that a carry from the LSD to the MSD can arise, but this should be double-checked.

You can continue this division process to extract the next digits, until the MSD becomes 0 (then continue with the LSD alone).

In your example case

M = 0xEE = 238 = 10 * 23 + 8, N = 0xDDCCBBAA = 3721182122 = 10 * 372118212 + 2

The unit digit is Nr = (6 * 8 + 2) % 10 = 0.

The quotient by 10 is

M' = 238 / 10 = 23, L' = 429496729 * 8 + 372118212 + (6 * 8 + 2) / 10 = 3808092049.

(As you can check, 23 * 2^32 + 3808092049= 102592339857.)

The next digit is N'r = (6 * 3 + 9) % 10 = 7.

The quotient by 10 is

M" = 23 / 10 = 2, L" = 429496729 * 3 + 380809204 + (6 * 3 + 9) / 10 = 1669299393.

(As you can check, 2 * 2^32 + 1669299393 = 10259233985.)

The next digit is N"r = (6 * 2 + 3) % 10 = 5.

The quotient by 10 is

M"' = 2 / 10 = 0, L"' = 429496729 * 2 + 166929939 + (6 * 2 + 3) / 10 = 1025923398.

As M"' = 0, you can now continue the conversion in pure 32 bits.

Upvotes: 0

chux
chux

Reputation: 153498

Could create a generic routine to handle any size byte array.

#include <string.h>

char *convert_10base_decimal_number(char *dest, size_t dsize, unsigned char *a,
    size_t asize) {

  if (dsize == 0)
    return NULL;
  char *d = dest + dsize - 1;
  *d = '\0';
  size_t ai = 0;
  do {
    // mod 10
    unsigned carry = 0;
    for (size_t i = ai; i < asize; i++) {
      carry = carry * 256 + a[i];
      a[i] = carry / 10;
      carry %= 10;
    }
    if (d == dest)
      return NULL;
    d--;
    *d = carry + '0';
    if (a[ai] == 0)
      ai++;
  } while (ai < asize);
  memmove(dest, d, dsize - (d - dest));
  return (dest);
}

int main(void) {
  unsigned char a[] = { 0xEE, 0xDD, 0xCC, 0xBB, 0xAA };
  char buf[50];

  puts(convert_10base_decimal_number(buf, sizeof buf, a, sizeof a));
  // 1025923398570

  return 0;
}

This method does consume the array a.

Upvotes: 1

V-X
V-X

Reputation: 3029

char a[5] = {0xEE, 0xDD, 0xCC, 0xBB, 0xAA};

// @Shmoopy's piece of code
int x = a[0] | (a[1] << 8) | (a[2] << 16) || (a[3] << 24);
int y = a[4];

// making long long from x and y, where y is the mo;
long long z = (long long)y << 32 | x;

// conversion of long long to string with base 10 (2^64 has max 19 decimal digits)
char str[20] = {};
lltoa(z, str, 10);
printf("The number is %s.\n", str);

Upvotes: 0

Shmoopy
Shmoopy

Reputation: 5534

long x,y;
x = a[0] | (a[1] << 8) | (a[2] << 16) || (a[3] << 24)
y = a[4]

So x is 0xEEDDCCBB and y is 0xAA You can use sprintf to convert x to a string and then concatenate it to y.

Upvotes: 0

Related Questions