如何在没有-
运算符的情况下减去 C 中的两个整数?
17 回答
int a = 34;
int b = 50;
您可以使用否定和加 1 将 b 转换为负值:
int c = a + (~b + 1);
printf("%d\n", c);
-16
这是二进制补码否定。当您想要否定值或子跟踪它时使用“-”运算符时,处理器正在执行此操作。
转换浮点数更简单。只需否定第一位(shoosh 为您提供了如何执行此操作的示例)。
编辑:
好,朋友们。我放弃。这是我的编译器独立版本:
#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's 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);
现在我们完全独立于有符号值约定。在我的方法结果中,所有整数都将存储为二进制补码 - 所以你必须小心更大的整数(它们必须以 0 位开头)。
Pontus 是对的,C 标准不强制要求 2 的补码(即使它是事实上的硬件标准)。+1 菲尔的创造性答案;这是另一种在不使用标准库或 -- 运算符的情况下获得 -1 的方法。
C 规定了三种可能的表示,因此您可以嗅探正在运行的表示并为每个表示不同的 -1:
negation= ~1;
if (negation+1==0) /* one's complement arithmetic */
minusone= ~1;
else if (negation+2==0) /* two's complement arithmetic */
minusone= ~0;
else /* sign-and-magnitude arithmetic */
minusone= ~0x7FFFFFFE;
r= a+b*minusone;
值 0x7FFFFFFFE 取决于您感兴趣的整数类型的宽度(“值位”的数量);如果未指定,您需要做更多的工作来找出答案!
- + 无位设置
- + 独立于语言
- + 可以针对不同的数字类型进行调整(int、float 等)
- - 几乎可以肯定不是你的 C 作业答案(可能是关于位)
展开 ab:
ab = a + (-b) = a + (-1).b
制造-1:
浮动:pi = asin(1.0); (与 minusone_flt = sin(3.0/2.0*pi); 数学.h) 或 = cos(pi) 或 = log10(0.1) 复杂:减号_cpx = (0,1)**2;//我平方 整数:减号整数 = 0;minusone_int--;// 或转换上面的浮点数之一
a - b = c
将自己限制在数字空间 0 <= c < (a+b) 中:
(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+bb).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,则 ba>0,所以:
c.mod(a+b) = c c = 2a.mod(a+b)
因此,如果 a 总是大于 b,那么这将起作用。
鉴于在 C 中不强制要求对整数进行编码以支持二进制补码,因此迭代直到完成。如果他们希望您跳过燃烧的箍,则无需高效!
int subtract(int a, int b)
{
if ( b < 0 )
return a+abs(b);
while (b-- > 0)
--a;
return a;
}
愚蠢的问题......可能是愚蠢的采访!
要在 C 中减去两个整数,您只需要:
int subtract(int a, int b)
{
return a + (~b) + 1;
}
我不相信浮点数或双精度数(如整数)有一个简单而优雅的解决方案。因此,您可以将浮点数转换为数组并应用与此处模拟的算法类似的算法
如果要对浮点数执行此操作,请从正数开始并更改其符号位,如下所示:
float f = 3;
*(int*)&f |= 0x80000000;
// now f is -3.
float m = 4 + f;
// m = 1
您也可以使用适当的 64 位整数对双精度数执行此操作。例如,在 Visual Studio 中,这是 __int64。
我想这
b - a = ~( a + ~b)
装配(蓄能器)样式:
int result = a;
result -= b;
由于问题要求整数 not int
s,您可以实现一个小的解释器,而不是使用Church numbers。
为每个可能的 int-int 情况创建一个查找表!
未测试。不使用 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;
}
}
假设 an 的长度int
远小于 255,并且 snprintf/sscanf 往返不会产生任何未指定的行为(对吗?对吗?)。
减法可以使用计算a - b == a + (-b).
选择:
#include <math.h>
int moreSillyNegate(int x) {
return x * ilogb(0.5); // ilogb(0.5) == -1;
}
这将使用整数溢出来工作:
#include<limits.h>
int subtractWithoutMinusSign(int a, int b){
return a + (b * (INT_MAX + INT_MAX + 1));
}
这也适用于浮点数(假设你制作了一个浮点数版本……)
对于任何数据类型的最大范围,反码提供减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] 的值。谢谢你.....愿这对你有帮助
如果:
- Minuend 大于或等于
0
, 或 - 减数大于或等于
0
, 或 - 减数和被减数小于
0
将 Minuend 乘以-1
并将结果添加到 Subtrahend:
SUB + (MIN * -1)
否则将被减数乘以1
并将结果添加到减数。
SUB + (MIN * 1)
示例(在线试用):
#include <stdio.h>
int subtract (int a, int b)
{
if ( a >= 0 || b >= 0 || ( a < 0 && b < 0 ) )
{
return a + (b * -1);
}
return a + (b * 1);
}
int main (void)
{
int x = -1;
int y = -5;
printf("%d - %d = %d", x, y, subtract(x, y) );
}
输出:
-1 - -5 = 4
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);
void main()
{
int a=5;
int b=7;
while(b--)a--;
printf("sud=%d",a);
}