仅使用增量、循环、赋值、归零的减法运算

Posted

技术标签:

【中文标题】仅使用增量、循环、赋值、归零的减法运算【英文标题】:Subtraction operation using only increment, loop, assign, zero 【发布时间】:2016-03-08 18:56:36 【问题描述】:

我正在尝试仅使用以下运算来构建减法、加法、除法、乘法和其他运算:

    incr(x) - 一旦这个函数被调用,它会将 x + 1 分配给 x assign(x, y) - 这个函数会将 y 的值赋给 x (x = y) zero(x) - 此函数会将 0 分配给 x (x = 0) 循环 X - 括号内的操作将被执行 X 次

使用以下规则可以直接实现加法(添加),如下所示:

ADD (x, y) 
 loop X 
   y = incr (y)
 
return y

但是,我正在努力实现 减法。我认为所有其他需要的操作都可以使用减法完成。

任何提示将不胜感激。

【问题讨论】:

你确定这是可能的吗?您创建的任何新值似乎都是输入的固定常数或正仿射函数。 可能是,我听到了这个问题。自己没见过。但可以肯定的是,没有像递减这样的功能。 你可以有负数吗? @AaditMShah 不,不允许 @templatetypedef 确实有可能。请参阅下面的答案。 【参考方案1】:

Stephen Cole Kleene 设计了一种使用整数加法执行整数减法的方法。但是,它假定您不能有负整数。例如:

0 - 1 = 0
1 - 1 = 0
2 - 1 = 1
3 - 1 = 2
4 - 1 = 3
5 - 2 = 3
6 - 3 = 3
6 - 4 = 2
6 - 5 = 1
6 - 6 = 0
6 - 7 = 0

在您的问题中,您使用增量操作实现了加法操作。

同样,你可以使用减法操作来实现减法操作,如下所示:

sub(x, y) 
    loop y
         x = decr(x) 
    return x

现在,我们需要做的就是实现递减操作。

这就是 Kleene 的天才之处:

decr(x) 
    y = 0
    z = 0

    loop x 
        y = z
        z = incr(z)
    

    return y

在这里,我们使用了所有四个操作。它是这样工作的:

    我们有两个基本情况,y0 的基本情况)和z1 的基本情况):

    y = 0 - 1 = 0
    z = 1 - 1 = 0
    

    因此,我们将它们都初始化为0

    x0 时,我们运行循环0 次(即从不),然后我们简单地返回y = 0

    x1 时,我们运行一次循环,分配y = z,然后简单地返回y = z = 0

请注意,每次我们运行循环时,y 保存当前迭代的结果,而 z 保存下一次迭代的结果。这就是我们需要两个基本案例的原因。递减函数不是连续函数。这是一个piecewise 函数:

decr(0)     = 0
decr(n + 1) = n

Kleene 在去看牙医时意识到了这一点,牙医拔掉了他的两颗牙齿。他在试图解决这个问题时感到很沮丧,当牙医拔出他的两颗牙齿时,他意识到他需要两个基本病例。

【讨论】:

解释得很好!您能说一下如何仅使用给定的操作来检查两个变量的相等性吗? - @Aadit M Shah @koruj 这当然是可能的。如果您将其作为问题发布,那么我将为您提供答案。 @korujzade 我在这里回答了你的问题:***.com/questions/34829670/…

以上是关于仅使用增量、循环、赋值、归零的减法运算的主要内容,如果未能解决你的问题,请参考以下文章

使用增量、循环、赋值、归零进行除法运算

如果只需要结果的低位部分,哪些 2 的补码整数运算可以在不将输入中的高位归零的情况下使用?

如果只需要结果的低部分,哪些 2 的补码整数运算可以在不将输入中的高位归零的情况下使用?

使用增量和减量运算符进行加法和减法。 C++

在 C 中将二维数组归零的最快方法是啥?

可以使用数学运算符 *、/、+、-、^ 将非零数转换为 1 吗?