Как я могу вычесть два целых числа в C без оператора -
?
Вычитание без знака "минус"
Ответ 1
int a = 34;
int b = 50;
Вы можете преобразовать значение b в отрицательное значение с помощью отрицания и добавить 1:
int c = a + (~b + 1);
printf("%d\n", c);
-16
Это два отрицания знака дополнения. Процессор делает это, когда вы используете оператор "-", когда хотите отменить значение или вычесть его.
Преобразование float проще. Просто отрицайте первый бит (shoosh дал вам пример, как это сделать).
EDIT:
Хорошо, ребята. Я сдаюсь. Вот моя независимая от компилятора версия:
#include <stdio.h>
unsigned int adder(unsigned int a, unsigned int b) {
unsigned int loop = 1;
unsigned int sum = 0;
unsigned int ai, bi, ci;
while (loop) {
ai = a & loop;
bi = b & loop;
ci = sum & loop;
sum = sum ^ ai ^ bi; // add i-th bit of a and b, and add carry bit stored in sum i-th bit
loop = loop << 1;
if ((ai&bi)|(ci&ai)|(ci&bi)) sum = sum^loop; // add carry bit
}
return sum;
}
unsigned int sub(unsigned int a, unsigned int b) {
return adder(a, adder(~b, 1)); // add negation + 1 (two complement here)
}
int main() {
unsigned int a = 35;
unsigned int b = 40;
printf("%u - %u = %d\n", a, b, sub(a, b)); // printf function isn't compiler independent here
return 0;
}
Я использую unsigned int, чтобы любой компилятор обрабатывал его одинаково.
Если вы хотите вычесть отрицательные значения, сделайте так:
unsgined int negative15 = adder(~15, 1);
Теперь мы полностью независимы от условных условных условных обозначений. В результате моего подхода все ints будут сохранены как два дополнения - поэтому вам нужно быть осторожными с большими ints (они должны начинаться с 0 бит).
Ответ 2
Понтус прав, 2 дополнения не санкционированы стандартом C (даже если это фактический аппаратный стандарт). +1 для творческих ответов Фила; здесь другой подход к получению -1 без использования стандартной библиотеки или оператора.
C задает три возможных представления, поэтому вы можете нюхать, что находится в действии, и получать разные -1 для каждого:
negation= ~1;
if (negation+1==0) /* one complement arithmetic */
minusone= ~1;
else if (negation+2==0) /* two complement arithmetic */
minusone= ~0;
else /* sign-and-magnitude arithmetic */
minusone= ~0x7FFFFFFE;
r= a+b*minusone;
Значение 0x7FFFFFFFE будет зависеть от ширины (числа битов значения) целого числа, которое вас интересует; если не указано, у вас есть больше работы, чтобы найти это!
Ответ 3
- + Нет настройки бита
- + независимый язык
- + Может быть настроен для разных типов номеров (int, float и т.д.)
- - Почти наверняка не ваш домашний ответ на C (который, вероятно, будет о битах)
Разверните a-b:
a-b = a + (-b) = a + (-1).b
Производство -1:
float: pi = asin(1.0); (with minusone_flt = sin(3.0/2.0*pi); math.h) or = cos(pi) or = log10(0.1) complex: minusone_cpx = (0,1)**2; // i squared integer: minusone_int = 0; minusone_int--; // or convert one of the floats above
Ответ 4
Учитывая, что целые числа кодирования для поддержки двух дополнений не обязательны в C, повторите итерацию до завершения. Если они хотят, чтобы вы перепрыгнули через пылающие обручи, не нужно быть эффективным!
int subtract(int a, int b)
{
if ( b < 0 )
return a+abs(b);
while (b-- > 0)
--a;
return a;
}
Глупый вопрос... возможно, глупое интервью!
Ответ 5
Если вы хотите сделать это для поплавков, начните с положительного числа и измените его бит знака следующим образом:
float f = 3;
*(int*)&f |= 0x80000000;
// now f is -3.
float m = 4 + f;
// m = 1
Вы также можете сделать это для удвоений, используя соответствующее 64-битное целое число. в visual studio это, например, __int64.
Ответ 6
+ Нет настройки бита + независимый язык + Независимо от типа номера (int, float и т.д.) - Требуется a > b (т.е. положительный результат) - Почти наверняка не ваш домашний ответ на C (который, вероятно, будет о битах)
a - b = c
ограничиваясь числовым пространством 0 <= c < (А + б):
(a - b) mod(a+b) = c mod(a+b) a mod(a+b) - b mod(a+b) = c mod(a+b)
упрощение второго члена:
(-b).mod(a+b) = (a+b-b).mod(a+b) = a.mod(a+b)
подставляя:
a.mod(a+b) + a.mod(a+b) = c.mod(a+b) 2a.mod(a+b) = c.mod(a+b)
если b > a, тогда b-a > 0, поэтому:
c.mod(a+b) = c c = 2a.mod(a+b)
Итак, если a всегда больше b, это будет работать.
Ответ 7
Посмотрите здесь: Добавить/вычесть с помощью побитовых операторов
Ответ 8
Для вычитания в C двух целых чисел вам нужно только:
int subtract(int a, int b)
{
return a + (~b) + 1;
}
Я не считаю, что есть простое элегантное решение для чисел с плавающей точкой или двойным числом, например, для целых чисел. Таким образом, вы можете преобразовать свои числа с плавающей запятой в массивы и применить алгоритм, похожий на один симулированный здесь
Ответ 9
Я полагаю, что это
b - a = ~ (a + ~ b)
Ответ 10
Сборка (аккумулятор):
int result = a;
result -= b;
Ответ 11
Поскольку вопрос задан целыми числами не int
s, вы можете реализовать небольшой интерпретатор, чем использовать цифры церкви.
Ответ 12
Создайте таблицу поиска для каждого возможного случая int-int!
Ответ 13
Не тестировалось. Без использования 2-х дополнений:
#include <stdlib.h>
#include <stdio.h>
int sillyNegate(int x) {
if (x <= 0)
return abs(x);
else {
// setlocale(LC_ALL, "C"); // if necessary.
char buffer[256];
snprintf(buffer, 255, "%c%d", 0x2d, x);
sscanf(buffer, "%d", &x);
return x;
}
}
Предполагая, что длина int
намного меньше 255, а snprintf/sscanf round-trip не приведет к неуказанному поведению (правильно?)?
Вычитание может быть вычислено с помощью a - b == a + (-b).
Альтернатива:
#include <math.h>
int moreSillyNegate(int x) {
return x * ilogb(0.5); // ilogb(0.5) == -1;
}
Ответ 14
Это будет работать с использованием целочисленного переполнения:
#include<limits.h>
int subtractWithoutMinusSign(int a, int b){
return a + (b * (INT_MAX + INT_MAX + 1));
}
Это также работает для float (при условии, что вы делаете float-версию...)
Ответ 15
Для максимального диапазона любого типа данных одно дополнение обеспечивает отрицательное значение, уменьшенное на 1 до любого соответствующего значения. например:
~ 1 -------- > -2
~ 2 --------- > -3
и так далее... Я покажу вам это наблюдение, используя небольшой фрагмент кода
#include<stdio.h>
int main()
{
int a , b;
a=10;
b=~a; // b-----> -11
printf("%d\n",a+~b+1);// equivalent to a-b
return 0;
}
Выход: 0
Примечание. Это допустимо только для диапазона типов данных. для типа данных int это правило будет применяться только для значения диапазона [-2,147,483,648 до 2,147,483,647].
Благодарю..... Пусть это поможет тебе.
Ответ 16
int num1, num2, count = 0;
Console.WriteLine("Enter two numebrs");
num1 = int.Parse(Console.ReadLine());
num2 = int.Parse(Console.ReadLine());
if (num1 < num2)
{
num1 = num1 + num2;
num2 = num1 - num2;
num1 = num1 - num2;
}
for (; num2 < num1; num2++)
{
count++;
}
Console.WriteLine("The diferrence is " + count);
Ответ 17
void main()
{
int a=5;
int b=7;
while(b--)a--;
printf("sud=%d",a);
}