Как объединить два целых числа в C
Переполнение стека отвечает на этот вопрос на многих других языках, но не на C. Поэтому я думал, что попрошу, поскольку у меня такая же проблема.
Как конкатенировать два целых числа в C?
Пример:
x = 11;
y = 11;
Мне хотелось бы z следующим образом:
z = 1111;
Другие примеры пытаются сделать это со строками. Каков способ сделать это без строк?
Я ищу эффективный способ сделать это на C, потому что в моем конкретном использовании это происходит во временной критичной части кода.
Спасибо в Advance!
Ответы
Ответ 1
unsigned concatenate(unsigned x, unsigned y) {
unsigned pow = 10;
while(y >= pow)
pow *= 10;
return x * pow + y;
}
Доказательство компиляция/правильность/скорость
Я избегаю функций log10
и pow
, потому что я уверен, что они используют с плавающей запятой и медленны, поэтому это может быть быстрее на вашем компьютере. Может быть. Профиль.
Ответ 2
z = x * pow(10, log10(y)+1) + y;
Объяснение:
Сначала вы получите количество цифр переменной, которая должна быть второй:
int digits = log10(y)+1; // will be 2 in your example
Затем вы меняете другую переменную, умножая ее на 10 цифр.
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;
Ответ 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;
Здесь я бесстыдно скопировал myPow из fooobar.com/questions/79794/...
Ответ 4
Это может быть не оптимальное или быстрое решение, но никто не упомянул об этом, и он простой и может быть полезен.
Вы можете использовать sprintf()
и strtol()
.
char str[100];
int i=32, j=45;
sprintf(str, "%d%d", i, j);
int result=strtol(str, NULL, 10);
Сначала вы записываете в строку числа, следующие за другим, с помощью sprintf()
(как и вы печатаете на stdout с помощью printf()
), а затем конвертируете результирующую строку в число с strtol()
.
strtol()
возвращает a 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()
здесь.
Edit:
Как отмечал просветительский комментарий 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
вместе со своим знаком.
+
в %+d
приведет к печати знака номера.
Теперь напечатайте первое число и второе число до str
, но без знаковой части второго номера. Мы пропускаем знаковое число второго числа, игнорируя первый символ в temp
.
Наконец выполняется strtol()
.
Ответ 5
здесь другой способ сделать это:
int concat(int x, int y) {
int temp = y;
while (y != 0) {
x *= 10;
y /= 10;
}
return x + temp;
}
кто знает, какую производительность вы получите. просто попробуйте и посмотрите.
Ответ 6
Возможно, это сработает:
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;
}
код длинный, но простой.
исправьте меня, если будут какие-то ошибки.
Ответ 7
Вот вариант ответа @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;
}
Ответ 8
Вы также можете использовать макрос для объединения строк (простой способ)
#include<stdio.h>
#define change(a,b) a##b
int main()
{
int y;
y=change(12,34);
printf("%d",y);
return 0;
}
У него есть один недостаток. Мы не можем передавать аргументы в этом методе
Ответ 9
#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;
}