使用增量,循环,赋值,零分割操作

时间:2016-10-01 18:09:34

标签: algorithm math logic

我们只允许使用以下操作:

incr(x) - 调用此函数后,它会将x + 1分配给x

assign(x, y) - 此函数将y的值赋给x(x = y)

zero(x) - 此函数将0分配给x(x = 0)

loop X { } - 括号内的操作将执行X次

如何实施除法运算?

2 个答案:

答案 0 :(得分:2)

这个问题结合了另外两个已在SO中回答的帖子:

  1. Relational operations
  2. Subtraction operation
  3. 通过这些问题,我们可以了解如何实施sub(x,y)gt(x,y)lte(x,t)add(x,y)。 通过使用这些,我们可以实现除法运算 - ceil(x/y)floor(x/y)

    的Ceil(X / Y)

    div_ceil(x,y){
        r = 0
        loop x{
            z = 0
            l = gt(x,z)
            r = add(r,l)
            x = sub(x,y)
        }
        return r
    }
    

    <强>解释
    我们循环x次,每次从y中减去x,我们计算在x不再大于0之前所需的次数。当它大于0时,我们会在结果中添加1

    为什么循环运行x次?
    因为它是获得结果所需的最长时间。这是在y == 1,减去1 x次时给出的 - 我们将获得r == x

    地板(X / Y)

    div_floor(x,y){ 
        r = 0
        t = 0
        loop x{
            t = add(t,y)
            l = lte(t,x)
            r = add(r,l)
        }
        return r
    }
    

    或者,如果您愿意,只需使用上面的div_ceil方法,我们也可以获得floor(x/y)

    div_floor(x,y){
        z = div_ceil(x,y)
        k = div_ceil(incr(x),y)
        l = eq(z,k)
        z = sub(z,l)
        return z
    }
    

    只需比较x/yx+1/y的结果。如果它们相同,则意味着我们在dev(x,y)中进行了向上舍入(上限),因此我们需要减去1以得到最终结果。如果它们不相等,结果应该保持不变。

    测试&amp;备注

    请查看这些方法的正确性running live here 我在C ++中实现了所有函数,因此它们的行为完全相同(仅使用允许的操作)。

    我认为除以0是一种未定义的行为。在y==0的情况下,这些方法将返回一些值而不是错误。

答案 1 :(得分:2)

虽然Sarid的回答是正确的,但可以更有效地计算floor(x / y),如下所示:

divide(x, y) {
    x = incr(x)

    z = 0

    loop x {
        x = sub(x, y)
        l = isTrue(x)
        z = add(z, l)
    }

    return z
}

此处已定义addsub函数:

Subtraction operation using only increment, loop, assign, zero

isTrue函数定义如下:

isTrue(x) {
    y = false
    loop x { y = true }
    return y
}

请注意,我们之前已定义truefalse,如下所示:

false = 0
true  = incr(false)

此功能的唯一问题是divide(n, 0)返回n + 1而不是错误。