Stack Overflow 用许多其他语言回答了这个问题,但不是 C。所以我想我会问,因为我有同样的问题。
如何在 C 中连接两个整数?
例子:
x = 11;
y = 11;
我希望 z 如下:
z = 1111;
其他示例尝试使用字符串执行此操作。什么是没有字符串的方法?
我正在寻找一种在 C 中执行此操作的有效方法,因为在我的特定用法中,这将进入代码的时间关键部分。
提前致谢!
Stack Overflow 用许多其他语言回答了这个问题,但不是 C。所以我想我会问,因为我有同样的问题。
如何在 C 中连接两个整数?
例子:
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
andpow
函数,因为我很确定它们使用浮点并且速度很慢,所以这在您的机器上可能会更快。也许。轮廓。
z = 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()
返回的 along
可能是一个大于可存储在 a 中的值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()
不在an的范围内int
(即不在(包括)INT_MIN
和之间INT_MAX
),则发生错误。INT_MIN
并且INT_MAX
来自limits.h
。
如果字符串中的值太大而无法在 a 中表示long
,errno
则会因为溢出而被设置为ERANGE
(from )。errno.h
strtol()
在这里阅读。
编辑:
正如chqrlie的启发性评论所指出的那样,负数会给这种方法带来麻烦。
你可以使用这个或修改这个来解决这个问题
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
首先将第二个数字及其符号打印到字符数组中。
+
in将%+d
导致打印数字的符号。
现在打印第一个数字和第二个数字,str
但没有第二个数字的符号部分。我们通过忽略 中的第一个字符来跳过第二个数字的符号部分temp
。
终于strtol()
完成了。
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;
在这里,我无耻地从https://stackoverflow.com/a/1505791/1194873复制了 myPow
这是@Mooing Duck 答案的变体,它使用查找表来查找 10 的倍数(对于具有慢整数乘法的平台)它还返回 unsigned long long 以允许更大的值,并在查找表中使用 unsigned long long 来解释 @ chqrlie 关于无限循环的评论。如果可以保证组合输入不超过无符号,则可以更改这些输入。
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;
}
您还可以使用宏来连接字符串(简单的方法)
#include<stdio.h>
#define change(a,b) a##b
int main()
{
int y;
y=change(12,34);
printf("%d",y);
return 0;
}
它有一个缺点。我们不能在这个方法中传递参数
这是另一种方法:
int concat(int x, int y) {
int temp = y;
while (y != 0) {
x *= 10;
y /= 10;
}
return x + temp;
}
谁知道你会得到什么样的表现。只是试试看..
也许这会起作用:
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;
}
代码很长,但很简单。如果有任何错误,请纠正我。
改进了@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;
}
#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;
}