0

I have a string with length 28, that represent 1 number in radix 16.

long num=strtol(str,NULL,16);

But it is worked for small strings but not long string (it gave me a negative result). So for long string how can I translate it?

//--------------------------

Well I think there is only one way without creating bicycle. Use GMP. So simple code with how to use GMP will be good answer.

ZeroVash
  • 546
  • 4
  • 20
  • 2
    https://gmplib.org/ ? –  May 24 '16 at 00:02
  • well are there other methods? – ZeroVash May 24 '16 at 00:03
  • 1
    I think GCC has support for 128bit integers on 64bit machines. –  May 24 '16 at 00:05
  • Look at this: http://stackoverflow.com/questions/16088282/is-there-a-128-bit-integer-in-gcc –  May 24 '16 at 00:05
  • 2
    What exactly are you trying to do? Why not just leave it the way it is? – David Schwartz May 24 '16 at 00:06
  • @DavidSchwartz when it is a long string, the result will be incorrect (negative number). – ZeroVash May 24 '16 at 00:11
  • @alex_mike Right, so don't do that. Whatever it is you're trying to do (which we do not know) you'll have to do some other way. What are you trying to do exactly? – David Schwartz May 24 '16 at 00:17
  • @DavidSchwartz I have a number in radix 16 , I translate it in radix 10 – ZeroVash May 24 '16 at 00:18
  • 1
    Ahh, so you want to convert a large number represented in base 16 to that same number represented in base 10. In that case, I'd suggest using a library for that purpose. In C, either [GMP](https://gmplib.org/) or the [OpenSSL BIGNUM](https://www.openssl.org/docs/manmaster/crypto/bn.html) is probably your best choice. – David Schwartz May 24 '16 at 00:20
  • @DavidSchwartz well Im trying but get error * incompatible types when assigning to type ‘mpz_t’ from type ‘long int’* – ZeroVash May 24 '16 at 00:21
  • 1
    @alex_mike Why are you using `long int` for? It doesn't store representations of numbers in base 10 and it doesn't store representations of numbers in base 16. So what are you using it for? I suggested using the library types, not `long int`. – David Schwartz May 24 '16 at 00:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/112726/discussion-between-alex-mike-and-david-schwartz). – ZeroVash May 24 '16 at 00:24
  • `long` can only store numbers in a certain range. Your input is outside the range. What do you expect to happen? – M.M May 24 '16 at 01:09

3 Answers3

2

Well Thanks to @DavidSchwartz who helped me in comments. So the solution is to use GMP library:

mpz_t res;
mpz_init_set_str (res, str, 16);
gmp_fprintf(f1,"%s",mpz_get_str(NULL,10,res));
mpz_clear (res);

May be something wrong, but it worked somehow. If you find a mistake let me know, Ill change it for future people.

ZeroVash
  • 546
  • 4
  • 20
1

Since code is starting with a string representing an integer in base 16, could use a string to represent the base 10 number too.

Simple enough to convert one digit at a time.

Space management left for OP.

#include <stdio.h>
#include <stdlib.h>

char *baseNtobase10(char *s10, const char *s16, int n) {
  strcpy(s10, "0");
  size_t len = strlen(s10);
  while (*s16) {
    char sdigit[] = { *s16, 0 };
    char *endptr;
    int digit = (int) strtol(sdigit, &endptr, n);

    if (endptr == sdigit) return NULL;  // detect illegal digits

    // multiple s10[] = s10[] * n + digit
    for (size_t i = len; i-- > 0; ) {
      digit += (s10[i] - '0') * n;
      s10[i] = digit % 10 + '0';
      digit /= 10;
    }

    // handle carry oout
    while (digit) {
      memmove(s10 + 1, s10, len + 1);
      *s10 = digit % 10 + '0';
      digit /= 10;
      len++;
    }
    s16++;
  }
  return s10;
}

int main(void) {
  char s10[100];
  puts(baseNtobase10(s10, "123", 10));
  puts(baseNtobase10(s10, "123", 16));
  puts(baseNtobase10(s10, "1234567890123456789012345678", 16));
  return 0;
}

Output

123
291
369229998778771388878179932591736
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

I was going to suggest strtoll, but that only goes to 16 characters or 64 bits. I suggest you use the bigint library, which has way higher limits.

Alastair Brown
  • 1,598
  • 8
  • 12