Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to (zerop #*000) in common lisp?

Tags:

common-lisp

Is there an efficient way to check if a bitvector is all zeroes? (I'm using SBCL on Linux.) I've looked through the documentation but could not find a suitable function. The best I've come up with so far is:

(defun bit-zerop (array)
  (equal array (make-array (length array) :element-type 'bit)))

(bit-zerop #*000)

I've also tried

(defun bit-zerop (array)
  (dotimes (i (length array))
    (if (eql (sbit array i) 1)
        (return-from bit-zerop nil)))
  t)

but it is about 100 times slower on larger bit vectors than the first version. (Which is expected, as each 64bit word is read 64 times, I guess, instead of just once). Of course, the first version is sub-optimal as well as it must allocate a new array.

EDIT: timings for mentioned solutions.

EDIT 2: timings with type declarations.

(defun bit-zerop-1 (array)
  ;; (declare (simple-bit-vector array))
  (equal array (make-array (length array) :element-type 'bit)))

(defun bit-zerop-2 (array)
  ;; (declare (simple-bit-vector array))
  (every #'zerop array))

(defun bit-zerop-3 (array)
  ;; (declare (simple-bit-vector array))
  (loop
     for bit across array
     never (= bit 1)))

(defun bit-zerop-4 (array)
  ;; (declare (simple-bit-vector array))
  (not (find 1 array)))

(dolist (func '(bit-zerop-1 bit-zerop-2 bit-zerop-3 bit-zerop-4))
  (dolist (size '(10 100 1000))
    (let ((x (make-array size :element-type 'bit)))
      (format t "Testing ~a on ~a elements~%" func size)
      (time
       (dotimes (i 1000000)
         (funcall func x))))))

gives

===============================================
method         size 10    size 100    size 1000
------------------- untyped -------------------
bit-zerop-1    0.030 s     0.030 s      0.058 s
bit-zerop-2    0.112 s     1.000 s      9.324 s
bit-zerop-3    0.111 s     0.935 s      8.742 s
bit-zerop-4    0.047 s     0.047 s      0.063 s
-------------------- typed --------------------
bit-zerop-1    0.025 s     0.023 s      0.040 s
bit-zerop-2    0.036 s     0.315 s      3.005 s
bit-zerop-3    0.041 s     0.348 s      3.346 s
bit-zerop-4    0.010 s     0.012 s      0.026 s
===============================================
like image 569
Andrei Avatar asked Apr 22 '20 18:04

Andrei


People also ask

What does it mean to zero a weapon?

To zero in is to adjust a gun so a target is in its sights. Zeroing in also refers to other types of homing in and targeting. This term has to do with setting your sights on something, or focusing on something in some other way.

What does it mean to zero a scope?

Zeroing a rifle scope is the act of aligning the scope or optic with the barrel so that the crosshairs match where the bullet is going to fall.

What is zeroing in NCC?

Sight Adjustment or zeroing is the act of adjusting. rifle or pistol sights so that shots fired with them hit the. center of the target.

Can you zero a rifle without firing?

Sighting in a gun without firing the weapon is a relatively simple procedure. By using a boresighter (a device that indicates the rifle's projected point of impact), or by visually determining the point of impact by looking through the barrel at a predetermined spot, your rifle can be sighted in within minutes.


2 Answers

Here's an option:

(defun bit-vector-zerop (bit-vector)
  (not (find 1 bit-vector)))

This does not cons and is very efficient on SBCL. It's faster if you can declare the argument to be a bit-vector.

like image 174
Xach Avatar answered Dec 07 '22 22:12

Xach


I am not sure if there is any special bit logic function, see e.g. here.

But how about this?

(loop
  for bit across #*0000
  never (= bit 1))
like image 25
Martin Buchmann Avatar answered Dec 07 '22 22:12

Martin Buchmann