How to concatenate two integers in C

2019-01-09 12:46发布

问题:

Stack Overflow has this question answered in many other languages, but not C. So I thought I'd ask, since I have the same issue.

How does one concatenate two integers in C?

Example:

x = 11;
y = 11;

I would like z as follows:

z = 1111;

Other examples attempt to do this with strings. What is a way to do this without strings?

I'm looking for an efficient way to do this in C because in my particular usage, this is going into a time critical part of code.

Thanks in Advance!

回答1:

unsigned concatenate(unsigned x, unsigned y) {
    unsigned pow = 10;
    while(y >= pow)
        pow *= 10;
    return x * pow + y;        
}

Proof of compilation/correctness/speed

I avoid the log10 and pow functions, because I'm pretty sure they use floating point and are slowish, so this might be faster on your machine. Maybe. Profile.



回答2:

z = x * pow(10, log10(y)+1) + y;

Explanation:

First you get the number of digits of the variable that should come second:

int digits = log10(y)+1;  // will be 2 in your example

Then you "shift" the other variable by multiplying it with 10^digits.

int shifted = x * pow(10, digits);   // will be 1100 in your example

Finally you add the second variable:

z = shifted + y;   // 1111

Or in one line:

z = x * pow(10, (int)log10(y)+1) + y;


回答3:

int myPow(int x, int p)
{
     if (p == 0) return 1;
     if (p == 1) return x;

     int tmp = myPow(x, p/2);
     if (p%2 == 0) return tmp * tmp;
     else return x * tmp * tmp;
}
int power = log10(y);
z = x*myPow(10,power+1)+y;

Here I shamelessly copied myPow from https://stackoverflow.com/a/1505791/1194873



回答4:

This may not be an optimal or fast solution but no one mentioned it and it's a simple one and could be useful.

You could use sprintf() and a strtol().

char str[100];
int i=32, j=45;
sprintf(str, "%d%d", i, j);
int result=strtol(str, NULL, 10);

You first write to a string the numbers one followed by the another with sprintf() (just like you would print to the stdout with printf()) and then convert the resultant string to the number with strtol().

strtol() returns a long which may be a value greater than what can be stored in an int, so you may want to check the resultant value first.

int result;
long rv=strtol(str, NULL, 10);
if(rv>INT_MAX || rv<INT_MIN || errno==ERANGE)
{
    perror("Something went wrong.");
}
else
{
    result=rv;
}

If the value returned by strtol() is not within the range of an int (ie, not between (including) INT_MIN and INT_MAX), error occurred. INT_MIN and INT_MAX are from limits.h.

If the value of in the string is too big to be represented in a long, errno will be set to ERANGE (from errno.h) because of the overflow.

Read about strtol() here.

Edit:

As the enlightening comment by chqrlie pointed out, negative numbers would cause trouble with this approach.

You could use this or a modification of this to get around that

char str[100], temp[50];
int i=-32, j=45, result;
sprintf(temp, "%+d", j);
sprintf(str, "%d%s", i, temp+1);
long rv=strtol(str, NULL, 10);

First print the second number to a character array temp along with its sign.

The + in %+d will cause the sign of the number to be printed.

Now print the first number and the second number to str but without the sign part of the second number. We skip the sign part of the second number by ignoring the first character in temp.

Finally the strtol() is done.



回答5:

here's another way to do it:

int concat(int x, int y) {
    int temp = y;
    while (y != 0) {
        x *= 10;
        y /= 10;
    }
    return x + temp;
}

who knows what performance you'll get. just try and see..



回答6:

Maybe this will work:

int x=11,y=11,temp=0;
int z=x;
while(y>0)
{
    // take reciprocal of y into temp
    temp=(temp*10)+(y%10);       
    y=y/10;
}
while(temp>0)
{
    // take each number from last of temp and add to last of z
    z=(z*10)+(temp%10);      
    temp=temp/10;
}

code is lengthy , but is simple. correct me if there is any mistakes.



回答7:

Here is a variation of @Mooing Duck's answer that uses a lookup table for multiples of 10 (for platform's with slow integer multiply) It also returns unsigned long long to allow for larger values and uses unsigned long long in the lookup table to account for @chqrlie's comment about infinite loops. If the combined inputs can be guaranteed to not exceed unsigned, those could be changed.

static const unsigned long long pow10s[] = {
   10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000
};
unsigned long long concat(unsigned x, unsigned y) {
    const unsigned long long *p = pow10s;
    while (y >= *p) ++p;
    return *p * x +y;        
}


回答8:

#include<iostream>
using namespace std;

int main()
{
    int a=0,b=0,count=0,c=0,t=0;
    cout<<"enter 2 no"<<endl;
    cin>>a>>b;
    t=b;

    while(b!=0)
    {
        b=b/10;
        count++;
    }

    while(count!=0)
    {
        a=a*10;
        count--;
        c=a+t;
    }

    cout<<"concate no is:"<<c;
}