虽然Stack Overflow已经回答了很多其他语言的这个问题,但没有C语言的答案。因此我想问一下,因为我也遇到了同样的问题。
如何在C语言中连接(concatenate)两个整数?
示例:
x = 11;
y = 11;
我希望将 z 设为以下内容:z = 1111;
其他示例尝试使用字符串来实现此目的。有没有一种不使用字符串的方法呢?
我正在寻找一种在C语言中高效地实现此操作的方法,因为在我的特定用法中,这将进入代码的时间关键部分。
谢谢提前!
虽然Stack Overflow已经回答了很多其他语言的这个问题,但没有C语言的答案。因此我想问一下,因为我也遇到了同样的问题。
如何在C语言中连接(concatenate)两个整数?
示例:
x = 11;
y = 11;
我希望将 z 设为以下内容:z = 1111;
其他示例尝试使用字符串来实现此目的。有没有一种不使用字符串的方法呢?
我正在寻找一种在C语言中高效地实现此操作的方法,因为在我的特定用法中,这将进入代码的时间关键部分。
谢谢提前!
unsigned concatenate(unsigned x, unsigned y) {
unsigned pow = 10;
while(y >= pow)
pow *= 10;
return x * pow + y;
}
我避免使用log10
和pow
函数,因为我相当确定它们使用浮点数并且速度较慢,所以这个方法在您的机器上可能更快。也许。进行分析。
y >= pow
,我认为concatenate(1,10)
不应该等于20。 - Daniel Fischerconcatenate(1, 1000000000)
。你可以在while
循环内部加入if (pow > UINT_MAX / 10) return y;
来避免这种情况。 - chqrliez = x * pow(10, log10(y)+1) + y;
解释:
首先获取应该排在第二位的变量的数字个数:
int digits = log10(y)+1; // will be 2 in your example
然后您可以通过将另一个变量乘以10^digits来"移位"该变量。
int shifted = x * pow(10, digits); // will be 1100 in your example
最后您需要添加第二个变量:
z = shifted + y; // 1111
或者一行代码实现:
z = x * pow(10, (int)log10(y)+1) + y;
这可能不是最优的或最快的解决方案,但没有人提到它,它很简单,也可能很有用。
您可以使用 sprintf()
和 strtol()
。
char str[100];
int i=32, j=45;
sprintf(str, "%d%d", i, j);
int result=strtol(str, NULL, 10);
sprintf()
将数字一和另一个数字写入字符串中(就像你使用printf()
打印到标准输出一样),然后使用strtol()
将结果字符串转换为数字。
strtol()
返回一个long
,它可能是大于可以存储在int
中的值,因此您可能需要先检查结果值。int result;
long rv=strtol(str, NULL, 10);
if(rv>INT_MAX || rv<INT_MIN || errno==ERANGE)
{
perror("Something went wrong.");
}
else
{
result=rv;
}
strtol()
返回的值不在int
的范围内(即不在包括INT_MIN
和INT_MAX
在内的范围内),则会出现错误。其中,INT_MIN
和INT_MAX
来自于limits.h
。long
,则由于溢出,errno
将被设置为ERANGE
(来自于errno.h
)。strtol()
的更多信息,请点击这里。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);
首先,将第二个数字及其符号打印到字符数组temp
中。
%+d
中的+
将导致数字的符号被打印出来。
现在,将第一个数字和第二个数字(但不包括第二个数字的符号部分)打印到str
中。我们通过忽略temp
中的第一个字符来跳过第二个数字的符号部分。
最后完成strtol()
。
errno
并将结果与INT_MIN
和INT_MAX
进行比较会很有帮助。i
或j
的负值也会导致问题。 - chqrlieINT_MIN
。 - J...S应该改为
if(rv>LONG_MAX || rv<LONG_MIN || errno==ERANGE)`。一般而言,这种方法无法检测出 'strtol("!!!", ...)'中的错误,因为errno不能确定地设置。 - chux - Reinstate Monicastatic 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;
}
#include<stdio.h>
#define change(a,b) a##b
int main()
{
int y;
y=change(12,34);
printf("%d",y);
return 0;
}
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;
在这里,我不好意思地抄袭了myPow函数,来源于https://dev59.com/GXI_5IYBdhLWcg3wJfkM#1505791
这里有另一种方法来做:
int concat(int x, int y) {
int temp = y;
while (y != 0) {
x *= 10;
y /= 10;
}
return x + temp;
}
谁知道你会得到什么性能。只有尝试才能知道。
concat(123, 0)
返回的是 123
而不是 1230
。建议使用 do ... while
循环。 - chux - Reinstate Monica这是对@Mooing Duck和@none答案的改进版本。
根据需要,只需将十进制数x
进行移位即可。
unsigned concatenate2(unsigned x, unsigned y) {
unsigned y_temp = y;
do { // do loop to insure at least one shift
x *= 10;
y_temp /= 10;
} while (y_temp > 0);
return x + y;
}
可以使用更广泛的数学方法来减少溢出可能性。@technosaurus
#include <inttypes.h>
uintmax_t concatenate2(unsigned x, unsigned y) {
uintmax_t x_temp = x;
unsigned y_temp = y;
do { // do loop to insure at least one shift
x_temp *= 10;
y_temp /= 10;
} while (y_temp > 0);
return x_temp + y;
}
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;
}
代码很长,但很简单。 如果有任何错误,请纠正我。
#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;
}
cin
和 cout
。而且,你回答了一个旧问题,已经有几个广受欢迎的答案。你的解决方案有何优势,值得发表吗? - honk
100 * x + y
这样的格式吗? - Kerrek SB