我们只允许使用以下操作:
incr(x)
- 调用此函数后,它会将x + 1分配给x
assign(x, y)
- 此函数将y的值赋给x(x = y)
zero(x)
- 此函数将0分配给x(x = 0)
loop X { }
- 括号内的操作将执行X次
如何实施除法运算?
答案 0 :(得分:2)
这个问题结合了另外两个已在SO中回答的帖子:
通过这些问题,我们可以了解如何实施sub(x,y)
,gt(x,y)
,lte(x,t)
和add(x,y)
。
通过使用这些,我们可以实现除法运算 - ceil(x/y)
和floor(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
。
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/y
和x+1/y
的结果。如果它们相同,则意味着我们在dev(x,y)
中进行了向上舍入(上限),因此我们需要减去1
以得到最终结果。如果它们不相等,结果应该保持不变。
请查看这些方法的正确性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
}
此处已定义add
和sub
函数:
Subtraction operation using only increment, loop, assign, zero
isTrue
函数定义如下:
isTrue(x) {
y = false
loop x { y = true }
return y
}
请注意,我们之前已定义true
和false
,如下所示:
false = 0
true = incr(false)
此功能的唯一问题是divide(n, 0)
返回n + 1
而不是错误。