所以,我现在正在阅读Land of Lisp,而且Lisp与我见过的其他编程语言完全不同。
无论如何,本书提供了一些我们打算输入CLISP REPL的代码:
(defparameter *small* 1)
(defparameter *big* 100)
(defun guess-my-number ()
(ash (+ *small* *big*) -1))
(defun smaller ()
(setf *big* (1- (guess-my-number)))
(guess-my-number))
(defun bigger ()
(setf *small* (1+ (guess-my-number)))
(guess-my-number))
现在,基本目标是创建一个数字猜谜游戏,其中用户/玩家选择一个数字,然后计算机试图猜测该数字。它通过让玩家报告计算机猜测的数字是高于还是低于玩家的号码来执行“二分搜索”,以找到玩家的号码。
我对ash
功能有点困惑。我的理解是这对二进制搜索至关重要,但我不确定为什么。这本书在某种程度上解释了它的作用,但它有点令人困惑。
ash
功能有什么作用?为什么通过*small*
添加到*big*
和-1
的参数?它是如何工作的?它对二进制搜索有什么作用?
答案 0 :(得分:4)
Google为您提供this page,其中解释了ash
是算术移位操作。所以(ash x -1)
向右移动x
一位,因此给出整数的一半。
答案 1 :(得分:3)
感谢Basile Starynkevitch对此问题的帮助......
无论如何,ash
执行了arithmetic shift operation。
在(ash x -1)
的情况下,它将x
向右移动一位,最终返回整数的一半。
例如,考虑二进制数1101
。二进制中的1101
相当于十进制的13
,可以这样计算:
8 * 1 = 8
4 * 1 = 4
2 * 0 = 0
1 * 1 = 1
8 + 4 + 0 + 1 = 13
运行(ash 13 -1)
将查看13的二进制表示,并执行-1的算术移位,将所有位向右移位1.这将产生110
的二进制输出(砍掉原始号码末尾的1
。二进制中的110
相当于十进制的6
,可以这样计算:
4 * 1 = 4
2 * 1 = 2
1 * 0 = 0
4 + 2 + 0 = 6
现在,13除以2不等于6,它相当于6.5,但是,因为它将返回整数的一半,6是可接受的答案。
这是因为二进制是基础2。
答案 2 :(得分:0)
问: ash函数有什么作用?为什么通过传递给 big 和-1的 small 参数?它是如何工作的?它对二进制搜索有什么作用?
它执行shifting bits的操作,更确切地说是Arithmetic shifting的操作,如针对Lisp的特定情况以图形方式解释/表示的:
> (ash 51 1)
102
当您执行(ash 51 1)
时,它会将51的二进制文件110011
向着左侧移1位,并得到1100110
,这会给您102以十进制表示。 (在this answer中说明了从二进制到十进制的转换过程)
在最正确的空白位置(称为 L 东 S 重要的 B 0
强>)。
> (ash 51 -1)
25
当您执行(ash 51 -1)
时,它将二进制数51即110011
向右侧移动1位(负值代表相反的方向),结果为{ {1}}的十进制数为102。
在这里丢弃冗余LSB。
在《 Lasp of Lisp》中举例说明的“ guss-my-number”游戏,我们有兴趣将范围减半或求平均值。因此,11001
将100 + 1 = 100/2减半得到50。我们可以按以下方式检查它:
(ash (+ *small* *big*) -1))
要注意的一件有趣的事是,您可以通过左移1位将整数的值翻倍,然后通过右移1位将其(大约)减半。