Pav*_*vel 1 lisp sbcl common-lisp
我正在尝试启用速度优化是 SBCL 2.3.1。编译如下代码:
(defun test (x y)
  (declare (optimize speed))
  (declare (type single-float x y))
  (+ x (sqrt y)))
产生以下注释:
; processing (DEFUN TEST ...)
; file: /var/tmp/slimeftWp5F
; in: DEFUN TEST
;     (SQRT RT-SPEC::Y)
; 
; note: unable to
;   optimize
; due to type uncertainty:
;   The result is a (VALUES (OR (COMPLEX SINGLE-FLOAT) (SINGLE-FLOAT -0.0))
;                           &OPTIONAL), not a (VALUES FLOAT &REST T).
;     (+ RT-SPEC::X (SQRT RT-SPEC::Y))
; 
; note: forced to do GENERIC-+ (cost 10)
;       unable to do inline float arithmetic (cost 2) because:
;       The second argument is a (OR (COMPLEX SINGLE-FLOAT) (SINGLE-FLOAT -0.0)), not a SINGLE-FLOAT.
;       The result is a (VALUES (OR SINGLE-FLOAT (COMPLEX SINGLE-FLOAT))
;                               &OPTIONAL), not a (VALUES SINGLE-FLOAT &OPTIONAL).
;       unable to do inline float arithmetic (cost 3) because:
;       The second argument is a (OR (COMPLEX SINGLE-FLOAT) (SINGLE-FLOAT -0.0)), not a (COMPLEX
;                                                                                        SINGLE-FLOAT).
;       The result is a (VALUES (OR SINGLE-FLOAT (COMPLEX SINGLE-FLOAT))
;                               &OPTIONAL), not a (VALUES (COMPLEX SINGLE-FLOAT)
;                                                         &OPTIONAL).
; 
; compilation unit finished
;   printed 2 notes
如果我理解正确,通用#'sqrt函数可能会返回不同类型的值。但我single-float向它提供了一个参数,是否可以以某种方式指定返回类型必须是什么single-float?
如果y为负数,平方根将是一个复数值:
> (test 1.5 -3.2)
#C(1.5 1.7888544)
如果要将浮点数限制为正值或零值,可以使用复合类型说明符:
单浮点 [单下限[单上限]]
例如如下:
(defun test (x y)
  (declare (optimize (speed 3)))
  (declare (type (single-float 0.0) x y))
  (+ x (sqrt y)))
在这种情况下对我来说没有任何警告。