• the unsigned right shift operator in CL >>>

    From Madhu@enometh@meer.net to comp.lang.lisp on Wed Oct 15 12:34:22 2025
    From Newsgroup: comp.lang.lisp


    I was trying to wrap my head the >>> operator

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift

    The unsigned right shift (>>>) operator returns a number whose
    binary representation is the first operand shifted by the
    specified number of bits to the right. Excess bits shifted off
    to the right are discarded, and zero bits are shifted in from
    the left. This operation is also called "zero-filling right
    shift", because the sign bit becomes 0, so the resulting number
    is always positive.

    This is what I understood but it looks too complicated

    (defun signed->unsigned (num bits)
    (if (< (- (1+ (expt 2 (1- bits)))) num 0)
    (+ (expt 2 bits) num)
    (if (< num (expt 2 bits))
    num
    (logand (1- (expt 2 bits)) num))))

    (defun fixed-width-ash (width x n)
    (if (> x 0)
    (logand (1- (ash 1 width)) (ash x n))
    (fixed-width-ash width
    (signed->unsigned x 32) n)))

    -9 >>> 2
    1073741821

    (fixed-width-ash 32 -9 -2)
    1073741821

    I'm looking for any insights on this.

    PS. Anyone know what happened to PJB, his online presence seems to have
    been discontinues.

    https://stackoverflow.com/questions/1691292/how-to-do-bit-wise-zero-filling-right-shift-in-scheme
    https://stackoverflow.com/questions/26151644/why-is-there-no-unsigned-left-shift-operator-in-java
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Aidan Kehoe@kehoea@parhasard.net to comp.lang.lisp on Thu Oct 16 19:04:13 2025
    From Newsgroup: comp.lang.lisp


    Ar an c||igi|| l|i d|-ag de m|! Deireadh F||mhair, scr|!obh Madhu:

    I was trying to wrap my head the >>> operator

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unsigned_right_shift

    The unsigned right shift (>>>) operator returns a number whose
    binary representation is the first operand shifted by the
    specified number of bits to the right. Excess bits shifted off
    to the right are discarded, and zero bits are shifted in from
    the left. This operation is also called "zero-filling right
    shift", because the sign bit becomes 0, so the resulting number
    is always positive.

    This is what I understood but it looks too complicated

    Something like:

    (defun fixed-width-ash (width value count)
    (ash (logand value (lognot (ash -1 width))) count))

    Construct an integer of the desired width that is all 1s, logand it with VALUE, then shift by COUNT.

    PS. Anyone know what happened to PJB, his online presence seems to have
    been discontinues.

    I hadnrCOt followed him, worth reading?

    https://stackoverflow.com/questions/1691292/how-to-do-bit-wise-zero-filling-right-shift-in-scheme
    https://stackoverflow.com/questions/26151644/why-is-there-no-unsigned-left-shift-operator-in-java
    --
    rCyAs I sat looking up at the Guinness ad, I could never figure out /
    How your man stayed up on the surfboard after fourteen pints of stoutrCO
    (C. Moore)
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Alan Bawden@alan@csail.mit.edu to comp.lang.lisp on Thu Oct 16 16:06:39 2025
    From Newsgroup: comp.lang.lisp

    Aidan Kehoe <kehoea@parhasard.net> writes:

    Ar an c||igi|| l|i d|-ag de m|! Deireadh F||mhair, scr|!obh Madhu:

    Something like:

    (defun fixed-width-ash (width value count)
    (ash (logand value (lognot (ash -1 width))) count))

    Construct an integer of the desired width that is all 1s, logand it
    with VALUE, then shift by COUNT.

    Your compiler will probably recognize that this is equivalent to:

    (defun fixed-width-ash (width value count)
    (ash (logandc2 value (ash -1 width)) count))

    But I would write it that way in the first place because I like to
    remember that the PDP-10 had an ANDCM instruction...
    --
    Alan Bawden
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Aidan Kehoe@kehoea@parhasard.net to comp.lang.lisp on Thu Oct 16 21:55:26 2025
    From Newsgroup: comp.lang.lisp


    Ar an s|-|| l|i d|-ag de m|! Deireadh F||mhair, scr|!obh Alan Bawden:

    Aidan Kehoe <kehoea@parhasard.net> writes:

    Ar an c||igi|| l|i d|-ag de m|! Deireadh F||mhair, scr|!obh Madhu:

    Something like:

    (defun fixed-width-ash (width value count)
    (ash (logand value (lognot (ash -1 width))) count))

    To comment on my own code; this wonrCOt do the desired fixed-width treatment of COUNT is positive, the logand would need to be done on the result of the #'ash. But the discussion was about implementing >>>, where COUNT is negative.

    Construct an integer of the desired width that is all 1s, logand it
    with VALUE, then shift by COUNT.

    Your compiler will probably recognize that this is equivalent to:

    (defun fixed-width-ash (width value count)
    (ash (logandc2 value (ash -1 width)) count))

    But I would write it that way in the first place because I like to
    remember that the PDP-10 had an ANDCM instruction...

    I donrCOt expect to remember any other PDP-10 instructions, but I might remember
    this one. Thanks!
    --
    rCyAs I sat looking up at the Guinness ad, I could never figure out /
    How your man stayed up on the surfboard after fourteen pints of stoutrCO
    (C. Moore)
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Madhu@enometh@meer.net to comp.lang.lisp on Thu Oct 23 16:34:22 2025
    From Newsgroup: comp.lang.lisp


    * Aidan Kehoe <87jz0utvlt.fsf@parhasard.net> :
    Wrote on Thu, 16 Oct 2025 21:55:26 +0100:
    Alan Bawden:
    Aidan Kehoe <kehoea@parhasard.net> writes:
    Something like:

    (defun fixed-width-ash (width value count)
    (ash (logand value (lognot (ash -1 width))) count))

    To comment on my own code; this won't do the desired fixed-width treatment of COUNT is positive, the logand would need to be done on the result of the #'ash.
    But the discussion was about implementing >>>, where COUNT is negative.

    Construct an integer of the desired width that is all 1s, logand it
    with VALUE, then shift by COUNT.

    Your compiler will probably recognize that this is equivalent to:

    (defun fixed-width-ash (width value count)
    (ash (logandc2 value (ash -1 width)) count))


    something like this then, does it miss out any case?

    (defun fixed-width-ash (width value count)
    (if (< count 0)
    (ash (logand value (lognot (ash -1 width))) count)
    (ash (logandc2 value (ash -1 width)) count)))



    But I would write it that way in the first place because I like to remember that the PDP-10 had an ANDCM instruction...

    I don't expect to remember any other PDP-10 instructions, but I might remember
    this one. Thanks!
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Madhu@enometh@meer.net to comp.lang.lisp on Thu Oct 23 16:38:56 2025
    From Newsgroup: comp.lang.lisp

    E R R A T A ERRATA jftr

    * In <m3ms5s3atl.fsf@pison.robolove.meer.net> :
    I Wrote on Wed, 15 Oct 2025 12:34:22 +0530:
    [...]
    This is what I understood but it looks too complicated

    (defun signed->unsigned (num bits)
    (if (< (- (1+ (expt 2 (1- bits)))) num 0)
    (+ (expt 2 bits) num)
    (if (< num (expt 2 bits))
    ^^^^^
    this condition should be (-1 < num (expt 2 bits))

    num
    (logand (1- (expt 2 bits)) num))))


    (defun fixed-width-ash (width x n)
    (if (> x 0)
    (logand (1- (ash 1 width)) (ash x n))
    (fixed-width-ash width
    (signed->unsigned x 32) n)))
    ^^^^ 32 here should be `width'


    -9 >>> 2
    1073741821

    (fixed-width-ash 32 -9 -2)
    1073741821

    [...]
    PS. Anyone know what happened to PJB, his online presence seems to have
    been discontinues(d)

    (PJB pascal j was of course a one time fairly prolific former poster CLL, who could be usually counted on for a review)
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Alan Bawden@alan@csail.mit.edu to comp.lang.lisp on Fri Oct 24 02:29:53 2025
    From Newsgroup: comp.lang.lisp

    Madhu <enometh@meer.net> writes:

    something like this then, does it miss out any case?

    (defun fixed-width-ash (width value count)
    (if (< count 0)
    (ash (logand value (lognot (ash -1 width))) count)
    (ash (logandc2 value (ash -1 width)) count)))

    Uh, guys, my point was that (logandc2 x y) and (logand x (lognot y))
    compute _exactly_ the same thing...
    --
    Alan Bawden
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Madhu@enometh@meer.net to comp.lang.lisp on Sat Oct 25 21:00:40 2025
    From Newsgroup: comp.lang.lisp


    * Alan Bawden <86plac3j8e.fsf@williamsburg.bawden.org> :
    Wrote on Fri, 24 Oct 2025 02:29:53 -0400:

    Madhu <enometh@meer.net> writes:

    something like this then, does it miss out any case?

    (defun fixed-width-ash (width value count)
    (if (< count 0)
    (ash (logand value (lognot (ash -1 width))) count)
    (ash (logandc2 value (ash -1 width)) count)))

    Uh, guys, my point was that (logandc2 x y) and (logand x (lognot y))
    compute _exactly_ the same thing...

    Oops. cut-paste typo on my part, sorry

    Aidan had written

    * <87wm4uu3j6.fsf@parhasard.net>
    |(defun fixed-width-ash (width value count)
    | (ash (logand value (lognot (ash -1 width))) count))
    |
    |Construct an integer of the desired width that is all 1s, logand it
    |with VALUE, then shift by COUNT.

    * <87jz0utvlt.fsf@parhasard.net>
    | To comment on my own code; this wonrCOt do the desired fixed-width
    | treatment of COUNT is positive, the logand would need to be done on
    | the result of the #'ash. But the discussion was about implementing
    | >>>, where COUNT is negative.

    So I wanted to add a alternate branch for (< count 0) which would call
    regular ash and do the logand, while retaining the proposed form (either version,) for the consequent branch

    if i hadn't C-yed the wrong kill I would have pasted

    (if (< count 0)
    (ash (logand value (lognot (ash -1 width))) count)
    (logand (1- (ash 1 width)) (ash value count)))

    but it would have still been wrong, given modular arithmetic

    leaving me hopelessly confused again. I have to find a reliable text.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@046-301-5902@kylheku.com to comp.lang.lisp on Thu Mar 12 18:00:17 2026
    From Newsgroup: comp.lang.lisp

    On 2025-10-24, Alan Bawden <alan@csail.mit.edu> wrote:
    Madhu <enometh@meer.net> writes:

    something like this then, does it miss out any case?

    (defun fixed-width-ash (width value count)
    (if (< count 0)
    (ash (logand value (lognot (ash -1 width))) count)
    (ash (logandc2 value (ash -1 width)) count)))

    Uh, guys, my point was that (logandc2 x y) and (logand x (lognot y))
    compute _exactly_ the same thing...

    So I'm looking for the logtrunc function and it's not there!

    Right, it's something I added in TXR Lisp, which is not in Common Lisp.

    (defun lsh (width value count) ;; ash -> arithmetic shift; lsh -> logical
    (ash (logtrunc value width) count))

    logtrunc truncates an integer to the specified number of binary
    digits, producing a nonnegative value. Negative integers are taken to be in the familiar "infinite two's complement", where we have a mantissa followed by an infinite number of sign bits that are 1, so that (logtrunc -1 8) produces 255, etc.
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Stefan Monnier@monnier@iro.umontreal.ca to comp.lang.lisp on Thu Mar 12 16:34:28 2026
    From Newsgroup: comp.lang.lisp

    So I'm looking for the logtrunc function and it's not there!

    Do you mean something like:

    (defun logtrunc (n bits)
    (mod n (ash 1 bits)))

    aka

    (defun logtrunc (n bits)
    (logand n (1- (ash 1 bits))))

    ?


    === Stefan
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Kaz Kylheku@046-301-5902@kylheku.com to comp.lang.lisp on Mon Mar 16 20:14:57 2026
    From Newsgroup: comp.lang.lisp

    On 2026-03-12, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
    So I'm looking for the logtrunc function and it's not there!

    Do you mean something like:

    (defun logtrunc (n bits)
    (mod n (ash 1 bits)))

    aka

    (defun logtrunc (n bits)
    (logand n (1- (ash 1 bits))))


    Yes, these look equivalent to me. A compiler could recognize
    these patterns and contract to a "logtrunc" operation that
    operates on the representation to do the truncation directly.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21d-Linux NewsLink 1.2