How to concatenate two integers in C
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!
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.
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;
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.
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