Le 01/02/2021 à 19:51, Marco Antoniotti a écrit :
Duh again!

What?


Note that the naive version is not necessarily worse than the "smart" one, on bignums. On numbers like (+ (expt 2 1000) (expt 2 10)), logand, lognot and even 1+ will have to process the whole bignum, with a lot of memory accesses, while the naive loop would access only one word.


MA

On Mon, Feb 1, 2021 at 7:47 PM Pascal Bourguignon <p...@informatimago.com <mailto:p...@informatimago.com>> wrote:

    Le 01/02/2021 à 09:45, Marco Antoniotti a écrit :
     > Duh!

    What?

    (1- (integer-length x)) is not ffs.

        76543 10
        vvvvv vv
    #b11010100
             ^
             2
    (ffs #b11010100) = 2
    (integer-length #b11010100) = 8
    (1- (integer-length #b11010100)) = 7

    (defun ffs/naive (n)
        (check-type n integer)
        (loop
          :for ffs :from 0
          :while (evenp n)
          :do (setf n (ash n -1))
          :finally (return ffs)))

    (ffs/naive #b11010100) ; --> 2

    The wikipedia page gives algorithms that are better than O(n), but with
    implementations in ℤ/2ⁿ instead of ℤ.

    Instead, you can extract the least significant 1 bit using (compose 1+
    lognot) and logand:


    (progn
        (format t "~@{~32B~%~}"
                #b11010100
                (logand #xffffffff (lognot #b11010100))
                (logand #xffffffff (1+ (lognot #b11010100)))
                (logand #xffffffff (logand #b11010100
                                      (1+ (lognot #b11010100)))))
        (format t "~D~%"
                (truncate (log (logand #b11010100
                                      (1+ (lognot #b11010100))) 2)))
        (values))
                              11010100
    11111111111111111111111100101011
    11111111111111111111111100101100
                                   100
    2

    (defun ffs (n)
        (check-type n integer)
        (truncate (log (logand n (1+ (lognot n))) 2)))

    (mapcar (function ffs)
              '(#b110101
                #b1101010
                #b11010100
                #b110101000
                #b1101010000))
    --> (0 1 2 3 4)



     > On Mon, Feb 1, 2021 at 9:42 AM d...@refined-audiometrics.com
    <mailto:d...@refined-audiometrics.com>
     > <mailto:d...@refined-audiometrics.com
    <mailto:d...@refined-audiometrics.com>> <d...@refined-audiometrics.com
    <mailto:d...@refined-audiometrics.com>
     > <mailto:d...@refined-audiometrics.com
    <mailto:d...@refined-audiometrics.com>>> wrote:
     >
     >     (1- (integer-length x))
     >
     >
     >>     On Feb 1, 2021, at 1:24 AM, Marco Antoniotti
     >>     <marco.antonio...@unimib.it
    <mailto:marco.antonio...@unimib.it>
    <mailto:marco.antonio...@unimib.it <mailto:marco.antonio...@unimib.it>>>
     >>     wrote:
     >>
     >>     Hi
     >>
     >>     I am wasti....  devoting some time to recreational hacking and I
     >>     bumped into an interesting bit fiddling operation.
     >>
     >>     I pored over the CLHS, but, while I may have missed something
     >>     obvious, I am not sure what would be the best way to implement
     >>     such a function using the standard operations.
     >>
     >>     Any ideas?
     >>b
     >>     Note that it appears that most HW does have an instruction to do
     >>     that directly.
     >>     Find first set - Wikipedia
     >>     <https://en.wikipedia.org/wiki/Find_first_set
    <https://en.wikipedia.org/wiki/Find_first_set>>
     >>
     >>     Thanks
     >>     Marco
     >>
     >>     --
     >>     Marco Antoniotti, Associate Professortel.+39 - 02 64 48 79 01
     >>     DISCo, Università Milano Bicocca U14
     >>     2043http://bimib.disco.unimib.it
    <http://bimib.disco.unimib.it> <http://bimib.disco.unimib.it/
    <http://bimib.disco.unimib.it/>>
     >>     Viale Sarca 336
     >>     I-20126 Milan (MI) ITALY
     >
     >
     >
     > --
     > Marco Antoniotti, Associate Professortel.+39 - 02 64 48 79 01
     > DISCo, Università Milano Bicocca U14
    2043http://bimib.disco.unimib.it <http://bimib.disco.unimib.it>
     > <http://bimib.disco.unimib.it/ <http://bimib.disco.unimib.it/>>
     > Viale Sarca 336
     > I-20126 Milan (MI) ITALY


-- __Pascal Bourguignon__



--
Marco Antoniotti, Associate Professortel.+39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043http://bimib.disco.unimib.it <http://bimib.disco.unimib.it/>
Viale Sarca 336
I-20126 Milan (MI) ITALY


--
__Pascal Bourguignon__

Reply via email to