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

Posted

技术标签:

【中文标题】使用增量、循环、赋值、归零进行除法运算【英文标题】:Divide operation using increment, loop, assign, zero 【发布时间】:2017-02-10 02:49:29 【问题描述】:

我们只能使用以下操作:

incr(x) - 一旦这个函数被调用,它会将 x + 1 分配给 x

assign(x, y) - 这个函数会将 y 的值赋给 x (x = y)

zero(x) - 这个函数会将 0 分配给 x (x = 0)

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

如何实现除法操作?

【问题讨论】:

我可以使用条件句吗? @HectorDavila 否,但您可以使用上述操作实现条件,如下所述:***.com/q/34829670/783743 这听起来像是一道作业题。你能展示你到目前为止的尝试吗? 数字(输入和输出)是整数吗?对于div(x,y),我可以假设x>=y吗? @A.Sarid 这些数字是非负整数,你不能假设x 大于y 【参考方案1】:

虽然 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而不是错误。

【讨论】:

是的,这是实现地板的另一种好方法。我想有很多方法可以实现它。我也为我的答案添加了另一种方式。 :)【参考方案2】:

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

    Relational operations Subtraction operation

从这些问题中我们可以看到如何实现sub(x,y)gt(x,y)lte(x,t)add(x,y)。 通过使用它们,我们可以实现除法运算 - ceil(x/y)floor(x/y)

单元格(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 次,每次我们从 x 中减去 y,我们计算直到 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 以获得地板结果。如果它们不相等,结果应该保持不变。


测试和注意事项

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

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

【讨论】:

不是计算结果的上限吗?我的意思是它将提醒计算为+1? sub(2, 4) 无论如何都会返回 0。 让我们用div(6,4) 来验证它。第二个减法将是sub(2,4),得到0。所以最后是r == 2。我的情况是ceiling(x/y)。我说的对吗? @AaditMShah 这是真的 - loop x 是静态分配 @A.Sarid 我认为解决方案不正确-sub(x, y) 其中x < y 将始终返回0,这意味着gte(x,0) 将返回1,然后我们增加r @A.Sarid 我认为floor(x/y) 实际上是理想的结果。

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

仅使用增量、循环、赋值、零的关系运算

C 语言高效编程与代码优化

C 语言高效编程与代码优化

c语言中num是啥意思

matlab学习笔记

BigDecimal进行除法运算时的坑