··········@yahoo.com writes:
> Below is a function to calculate CRC-16 (one possible variant). The
> question is: surely there is something to be done to make it more fast
> (it seems that tail-recursive version is as fast as dotimes/setf, at
> least in SBCL)? I'm not sure about correct type declarations, in
> particular.
[...]
> ;while (len--) crc = (crc << 8) ^ crctab[ ((crc >> (order-8)) & 0xff) ^
> *p++];
>
> (defun update-crc (buf len n crc)
> (declare (type (unsigned-byte 32) crc)
> (type (simple-array (unsigned-byte 8)) buf)
> (type fixnum len)
> (type fixnum n)
> (optimize speed))
> (if (zerop len) (logand #xffff (logxor crc #xffff))
> (update-crc
> buf (1- len) (1+ n)
> (logxor
> (ash crc 8)
> (aref *crc-table* (logxor (logand #xff (ash crc -8)) (aref buf
> n)))))))
If I remove (OPTIMIZE SPEED), the test fails with type error "CRC is
not of type (UNSIGNED-BYTE 32)"; I think you need to strip high bits
of new CRC.
(defun update-crc (buf len n crc)
(declare (type (unsigned-byte 32) crc)
(type (simple-array (unsigned-byte 8)) buf)
(type (integer 0 #.(1- most-positive-fixnum)) len n) ; so (1- LEN) and (1+ N) are FIXNUMs
(optimize speed (safety 0)))
(if (zerop len) (logand #xffff (logxor crc #xffff))
(update-crc
buf (1- len) (1+ n)
(logand (1- (ash 1 32))
(logxor
(ash crc 8)
(aref *crc-table* (logxor (logand #xff (ash crc -8)) (aref buf n))))))))
--
Regards,
Alexey Dejneka
"Alas, the spheres of truth are less transparent than those of
illusion." -- L.E.J. Brouwer