summaryrefslogtreecommitdiff
path: root/devdocs/elisp/bitwise-operations.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/elisp/bitwise-operations.html
new repository
Diffstat (limited to 'devdocs/elisp/bitwise-operations.html')
-rw-r--r--devdocs/elisp/bitwise-operations.html128
1 files changed, 128 insertions, 0 deletions
diff --git a/devdocs/elisp/bitwise-operations.html b/devdocs/elisp/bitwise-operations.html
new file mode 100644
index 00000000..790c8147
--- /dev/null
+++ b/devdocs/elisp/bitwise-operations.html
@@ -0,0 +1,128 @@
+ <h3 class="section">Bitwise Operations on Integers</h3> <p>In a computer, an integer is represented as a binary number, a sequence of <em>bits</em> (digits which are either zero or one). Conceptually the bit sequence is infinite on the left, with the most-significant bits being all zeros or all ones. A bitwise operation acts on the individual bits of such a sequence. For example, <em>shifting</em> moves the whole sequence left or right one or more places, reproducing the same pattern moved over. </p> <p>The bitwise operations in Emacs Lisp apply only to integers. </p> <dl> <dt id="ash">Function: <strong>ash</strong> <em>integer1 count</em>
+</dt> <dd>
+ <p><code>ash</code> (<em>arithmetic shift</em>) shifts the bits in <var>integer1</var> to the left <var>count</var> places, or to the right if <var>count</var> is negative. Left shifts introduce zero bits on the right; right shifts discard the rightmost bits. Considered as an integer operation, <code>ash</code> multiplies <var>integer1</var> by 2**<var>count</var>, and then converts the result to an integer by rounding downward, toward minus infinity. </p> <p>Here are examples of <code>ash</code>, shifting a pattern of bits one place to the left and to the right. These examples show only the low-order bits of the binary pattern; leading bits all agree with the highest-order bit shown. As you can see, shifting left by one is equivalent to multiplying by two, whereas shifting right by one is equivalent to dividing by two and then rounding toward minus infinity. </p> <div class="example"> <pre class="example">(ash 7 1) ⇒ 14
+;; <span class="roman">Decimal 7 becomes decimal 14.</span>
+…000111
+ ⇒
+…001110
+</pre>
+
+<pre class="example">(ash 7 -1) ⇒ 3
+…000111
+ ⇒
+…000011
+</pre>
+
+<pre class="example">(ash -7 1) ⇒ -14
+…111001
+ ⇒
+…110010
+</pre>
+
+<pre class="example">(ash -7 -1) ⇒ -4
+…111001
+ ⇒
+…111100
+</pre>
+</div> <p>Here are examples of shifting left or right by two bits: </p> <div class="example"> <pre class="example"> ; <span class="roman"> binary values</span>
+(ash 5 2) ; 5 = <span class="roman">…000101</span>
+ ⇒ 20 ; = <span class="roman">…010100</span>
+(ash -5 2) ; -5 = <span class="roman">…111011</span>
+ ⇒ -20 ; = <span class="roman">…101100</span>
+</pre>
+<pre class="example">(ash 5 -2)
+ ⇒ 1 ; = <span class="roman">…000001</span>
+</pre>
+<pre class="example">(ash -5 -2)
+ ⇒ -2 ; = <span class="roman">…111110</span>
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="lsh">Function: <strong>lsh</strong> <em>integer1 count</em>
+</dt> <dd>
+ <p><code>lsh</code>, which is an abbreviation for <em>logical shift</em>, shifts the bits in <var>integer1</var> to the left <var>count</var> places, or to the right if <var>count</var> is negative, bringing zeros into the vacated bits. If <var>count</var> is negative, then <var>integer1</var> must be either a fixnum or a positive bignum, and <code>lsh</code> treats a negative fixnum as if it were unsigned by subtracting twice <code>most-negative-fixnum</code> before shifting, producing a nonnegative result. This quirky behavior dates back to when Emacs supported only fixnums; nowadays <code>ash</code> is a better choice. </p> <p>As <code>lsh</code> behaves like <code>ash</code> except when <var>integer1</var> and <var>count1</var> are both negative, the following examples focus on these exceptional cases. These examples assume 30-bit fixnums. </p> <div class="example"> <pre class="example"> ; <span class="roman"> binary values</span>
+(ash -7 -1) ; -7 = <span class="roman">…111111111111111111111111111001</span>
+ ⇒ -4 ; = <span class="roman">…111111111111111111111111111100</span>
+(lsh -7 -1)
+ ⇒ 536870908 ; = <span class="roman">…011111111111111111111111111100</span>
+</pre>
+<pre class="example">(ash -5 -2) ; -5 = <span class="roman">…111111111111111111111111111011</span>
+ ⇒ -2 ; = <span class="roman">…111111111111111111111111111110</span>
+(lsh -5 -2)
+ ⇒ 268435454 ; = <span class="roman">…001111111111111111111111111110</span>
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="logand">Function: <strong>logand</strong> <em>&amp;rest ints-or-markers</em>
+</dt> <dd>
+<p>This function returns the bitwise AND of the arguments: the <var>n</var>th bit is 1 in the result if, and only if, the <var>n</var>th bit is 1 in all the arguments. </p> <p>For example, using 4-bit binary numbers, the bitwise AND of 13 and 12 is 12: 1101 combined with 1100 produces 1100. In both the binary numbers, the leftmost two bits are both 1 so the leftmost two bits of the returned value are both 1. However, for the rightmost two bits, each is 0 in at least one of the arguments, so the rightmost two bits of the returned value are both 0. </p> <p>Therefore, </p> <div class="example"> <pre class="example">(logand 13 12)
+ ⇒ 12
+</pre>
+</div> <p>If <code>logand</code> is not passed any argument, it returns a value of -1. This number is an identity element for <code>logand</code> because its binary representation consists entirely of ones. If <code>logand</code> is passed just one argument, it returns that argument. </p> <div class="example"> <pre class="example"> ; <span class="roman"> binary values</span>
+
+(logand 14 13) ; 14 = <span class="roman">…001110</span>
+ ; 13 = <span class="roman">…001101</span>
+ ⇒ 12 ; 12 = <span class="roman">…001100</span>
+</pre>
+
+<pre class="example">(logand 14 13 4) ; 14 = <span class="roman">…001110</span>
+ ; 13 = <span class="roman">…001101</span>
+ ; 4 = <span class="roman">…000100</span>
+ ⇒ 4 ; 4 = <span class="roman">…000100</span>
+</pre>
+
+<pre class="example">(logand)
+ ⇒ -1 ; -1 = <span class="roman">…111111</span>
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="logior">Function: <strong>logior</strong> <em>&amp;rest ints-or-markers</em>
+</dt> <dd>
+<p>This function returns the bitwise inclusive OR of its arguments: the <var>n</var>th bit is 1 in the result if, and only if, the <var>n</var>th bit is 1 in at least one of the arguments. If there are no arguments, the result is 0, which is an identity element for this operation. If <code>logior</code> is passed just one argument, it returns that argument. </p> <div class="example"> <pre class="example"> ; <span class="roman"> binary values</span>
+
+(logior 12 5) ; 12 = <span class="roman">…001100</span>
+ ; 5 = <span class="roman">…000101</span>
+ ⇒ 13 ; 13 = <span class="roman">…001101</span>
+</pre>
+
+<pre class="example">(logior 12 5 7) ; 12 = <span class="roman">…001100</span>
+ ; 5 = <span class="roman">…000101</span>
+ ; 7 = <span class="roman">…000111</span>
+ ⇒ 15 ; 15 = <span class="roman">…001111</span>
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="logxor">Function: <strong>logxor</strong> <em>&amp;rest ints-or-markers</em>
+</dt> <dd>
+<p>This function returns the bitwise exclusive OR of its arguments: the <var>n</var>th bit is 1 in the result if, and only if, the <var>n</var>th bit is 1 in an odd number of the arguments. If there are no arguments, the result is 0, which is an identity element for this operation. If <code>logxor</code> is passed just one argument, it returns that argument. </p> <div class="example"> <pre class="example"> ; <span class="roman"> binary values</span>
+
+(logxor 12 5) ; 12 = <span class="roman">…001100</span>
+ ; 5 = <span class="roman">…000101</span>
+ ⇒ 9 ; 9 = <span class="roman">…001001</span>
+</pre>
+
+<pre class="example">(logxor 12 5 7) ; 12 = <span class="roman">…001100</span>
+ ; 5 = <span class="roman">…000101</span>
+ ; 7 = <span class="roman">…000111</span>
+ ⇒ 14 ; 14 = <span class="roman">…001110</span>
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="lognot">Function: <strong>lognot</strong> <em>integer</em>
+</dt> <dd>
+<p>This function returns the bitwise complement of its argument: the <var>n</var>th bit is one in the result if, and only if, the <var>n</var>th bit is zero in <var>integer</var>, and vice-versa. The result equals -1 - <var>integer</var>. </p> <div class="example"> <pre class="example">(lognot 5)
+ ⇒ -6
+;; 5 = <span class="roman">…000101</span>
+;; <span class="roman">becomes</span>
+;; -6 = <span class="roman">…111010</span>
+</pre>
+</div> </dd>
+</dl> <dl> <dt id="logcount">Function: <strong>logcount</strong> <em>integer</em>
+</dt> <dd>
+<p>This function returns the <em>Hamming weight</em> of <var>integer</var>: the number of ones in the binary representation of <var>integer</var>. If <var>integer</var> is negative, it returns the number of zero bits in its two’s complement binary representation. The result is always nonnegative. </p> <div class="example"> <pre class="example">(logcount 43) ; 43 = <span class="roman">…000101011</span>
+ ⇒ 4
+(logcount -43) ; -43 = <span class="roman">…111010101</span>
+ ⇒ 3
+</pre>
+</div> </dd>
+</dl><div class="_attribution">
+ <p class="_attribution-p">
+ Copyright &copy; 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br>
+ <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Bitwise-Operations.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Bitwise-Operations.html</a>
+ </p>
+</div>