EMMERZOH
EMMERZOH

Reputation: 29

Convert int array into single integer in C

I have hit a bit of a roadblock and I was hoping someone could help.

Suppose you have:

int A[]={156,23,212,4,12};

And you would like to append it to give a single integer n=15623212412

How can I fix my code to do so?

int p, n=0, size=5; 
for(i=1;i<size;i++){
    p=10;

    while(A[i]>=p)
        p*=10;

    n*=p;  
    n+=A[i];
}

It needs to be in C and it needs to create integer n through a loop as the integers in and size of the array will change.

Upvotes: 1

Views: 12914

Answers (6)

Abhishek Yadav
Abhishek Yadav

Reputation: 81

You can first convert the integer array to string and then can convert it into a single integer, like this:

std::ostringstream os;
for (int i: res) {
    os << i;
}
std::string str(os.str());
stringstream geek(str);
int x = 0; 
geek >> x;

where res is an array.

Upvotes: 0

phuclv
phuclv

Reputation: 41794

You can try using a lookup table for powers of 10

const uint64_t powersOf10[] = { // use lookup to reduce multiplications
    1, 10,
    100, 1000,
    10000, 100000,
    1000000, 10000000,
    100000000, 1000000000, // the table can end here if A[i] is of type int
    10000000000, 100000000000,
    1000000000000, 10000000000000,
    100000000000000, 1000000000000000,
    10000000000000000, 100000000000000000,
    1000000000000000000, 10000000000000000000
};

int A[] = {156, 23, 212, 4, 12};
uint64_t *p10, n = 0; // or unsigned long long if uint64_t not available

for (int i = 0; i < sizeof(A)/sizeof(A[0]); i++)
{
    // get the length of A[i] by linear search
    p10 = powersOf10;
    while (*p10 < A[i]) p10++;

    n *= *p10;
    n += A[i];
}

You can change the linear search to a binary search, or using some optimized way to calculate log10 to get the index to powersOf10[]

If you just want to print then the simplest solution would be using sprintf. It'll work for arbitrarily long arrays

char output[MAX], *pos = output;
for (int i = 0; i < sizeof(A)/sizeof(A[0]); i++)
    pos += sprintf(pos, "%d", A[i]);

Upvotes: 0

Valdis Grinbergs
Valdis Grinbergs

Reputation: 453

There are a lot of good answers here, but I also like converting to string, then to a long long int. That was mentioned above, but let me add an implementation. It is simpler than some alternatives:

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

int main()
{
    int A[] = {156, 23, 212, 4, 12};
    int length = 5;
    char a_as_num[length][4];
    char string[15] = "\0";
    long long number;
    int i;

    for (i = 0; i < length; i++) {
        sprintf(a_as_num[i], "%d", A[i]); 
        strcat(string, a_as_num[i]);
    }
    number = atoll(string);
    printf("%lli\n", number);
    return 0;
}

Upvotes: 0

Paolo
Paolo

Reputation: 15827

I suggest this approach given that you know beforehand you're not going to overflow...

I'm using long as they are 64 bits on my architecture (they are treated as long long) If it's not your case use long long

long A[]={156,23,212,4,12};
long size = 5;

long i;
long j;
long n;
long k;

i = size;
j = 0;
n = 0;
k = 1;
while( true )
{
    if( j == 0 )
    {
        i--;
        if( i < 0 )
        {
            break;
        }
        j = A[ i ];
    }

    n += ( j % 10 ) * k;
    j /= 10;
    k *= 10;
}

printf("%ld\n", n); // <== final result printed

Upvotes: 0

Clifford
Clifford

Reputation: 93476

If the size of the array can be bigger you have to understand that a 32 bit integer is good for only nine decimal digits - log10(232), and that even a 64 bit integer is good for 19 decimal digits - log10(264). Either way, even your small example will not fit in a 32 bit int.

Also there is no real mathematical purpose or relationship in appending arbitrary integers in this way, especially as each has a variable number of decimal significant digits - any algorithm would have to take that into account.

So for the reasons given, attempting to solve the problem arithmetically is both over complex and inflexible; the simpler solution is to generate the result as a string.

int A[]={156,23,212,4,12};
int i = 0 ;
int index = 0 ;
const int length_A = sizeof(A) / sizeof(*A) ;
char astr[length_A * 10 ] ; // sized to accommodate worst case 
                            // string length for 32 bit int of INT_MAX.


for( i = 0; i < length_A; i++ )
{
    index += sprintf( &astr[index], "%d", A[i] ) ; 
}

printf( "%s", astr ) ;

If you really need an arithmetic solution and can work within the limits of the available integer data types, then I suggest that you use unsigned long long for the output and unsigned int for the input, then:

#include <stdio.h>
#include <math.h>

int main()
{
    unsigned int A[]={156,23,212,4,12};
    unsigned long long result = 0 ;
    int i = 0 ;
    const int length_A = sizeof(A) / sizeof(*A) ;

    for( i = 0; i < length_A; i++ )
    {
        result += A[i] ;
        if( i < length_A - 1)
        {
            int digits = (int)ceil( log10( (double)A[i+1] ) ) ;
            result *= (int)pow( 10, digits ) ;
        }
    }

    printf( "%llu\n", result ) ;

    return 0 ;
}

Upvotes: 1

R Sahu
R Sahu

Reputation: 206577

I see couple of problems:

  1. You are starting the for loop with i=1. It should be i=0.

  2. 15623212412 could be too big to fit in an int. It is on my machine. Use long or a bigger integral type.

By the way, I was able to detect the problem by adding a printf.

#include <stdio.h>

int main()
{
   int A[]={156,23,212,4,12};
   int p, size=5; 
   long n = 0;
   int i;

   for(i=0;i<size;i++){
       p=10;

       while(A[i]>=p)
          p*=10;

       n*=p;  
       n+=A[i];
       printf("n: %ld\n", n);
   }

   return 0;
}

Upvotes: 0

Related Questions