13

如何在没有-运算符的情况下减去 C 中的两个整数?

4

17 回答 17

19
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 位开头)。

于 2009-03-31T08:00:06.300 回答
13

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 取决于您感兴趣的整数类型的宽度(“值位”的数量);如果未指定,您需要做更多的工作来找出答案!

于 2009-03-31T15:26:37.023 回答
9
  • + 无位设置
  • + 独立于语言
  • + 可以针对不同的数字类型进行调整(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--;// 或转换上面的浮点数之一
于 2009-03-31T09:07:58.307 回答
6

  • + 无位设置
  • + 独立于语言
  • + 独立于数字类型(int、float 等)
  • -要求 a>b(即阳性结果)
  • - 几乎可以肯定不是你的 C 作业答案(可能是关于位)
  • 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,那么这将起作用。

    于 2009-03-31T08:44:07.133 回答
    5

    鉴于在 C 中不强制要求对整数进行编码以支持二进制补码,因此迭代直到完成。如果他们希望您跳过燃烧的箍,则无需高效!

    int subtract(int a, int b)
    {
      if ( b < 0 )
        return a+abs(b);
      while (b-- > 0)
        --a;
      return a;
    }
    

    愚蠢的问题......可能是愚蠢的采访!

    于 2009-03-31T07:49:42.503 回答
    3

    要在 C 中减去两个整数,您只需要:

    int subtract(int a, int b)
    {
        return a + (~b) + 1;
    }
    

    我不相信浮点数或双精度数(如整数)有一个简单而优雅的解决方案。因此,您可以将浮点数转换为数组并应用与此处模拟的算法类似的算法

    于 2009-03-31T08:01:32.820 回答
    2

    如果要对浮点数执行此操作,请从正数开始并更改其符号位,如下所示:

    float f = 3;
    *(int*)&f |= 0x80000000;
    // now f is -3.
    float m = 4 + f; 
    // m = 1
    

    您也可以使用适当的 64 位整数对双精度数执行此操作。例如,在 Visual Studio 中,这是 __int64。

    于 2009-03-31T07:59:13.730 回答
    1

    我想这

    b - a = ~( a + ~b)

    于 2009-03-31T08:06:23.540 回答
    1

    装配(蓄能器)样式:

    int result = a;
    result -= b;
    
    于 2009-03-31T08:31:36.787 回答
    0

    由于问题要求整数 not ints,您可以实现一个小的解释器,而不是使用Church numbers

    于 2009-03-31T08:27:41.167 回答
    0

    为每个可能的 int-int 情况创建一个查找表!

    于 2009-04-03T22:29:02.970 回答
    0

    未测试。不使用 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;
    }
    

    于 2010-06-09T10:08:50.710 回答
    0

    这将使用整数溢出来工作:

    #include<limits.h>    
    int subtractWithoutMinusSign(int a, int b){
             return a + (b * (INT_MAX + INT_MAX + 1));
    }
    

    这也适用于浮点数(假设你制作了一个浮点数版本……)

    于 2010-08-13T18:31:27.857 回答
    0

    对于任何数据类型的最大范围,反码提供减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] 的值。谢谢你.....愿这对你有帮助

    于 2017-03-06T19:22:03.840 回答
    0

    如果

    1. Minuend 大于或等于0, 或
    2. 减数大于或等于0, 或
    3. 减数和被减数小于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
    
    于 2020-05-30T08:38:03.357 回答
    -1
            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);
    
    于 2010-06-09T09:58:28.067 回答
    -1
    void main()
    {
    int a=5;
    int b=7;
    
    while(b--)a--;
    printf("sud=%d",a);
    
    }
    
    于 2010-07-06T09:54:01.627 回答