Bit twiddling is fundamentally the same as in other programming languages. However, Forth allows us to change base for easy interactive bit twiddling:
: binary 0x2 base ! ;
To set a bit (to 1) we use bit-wise or. E.g.
binary 10100011 00001000 or . <cr> 10101011 ok
To clear a bit, we need bit-wise and.
binary 10100011 11011111 and . <cr> 10000011 ok
Toggling a bit uses bit-wise xor. Here we toggle two bits:
binary 10100011 00110000 xor . <cr> 10010011 ok
We can pull the value of a bit with and. In Forth, zero values are false, while non-zero values are true.
binary 10100011 00100000 and [if] ." bit is set!" [else] ." bit is clear!" [then] <cr> bit is set! ok
We can pull, say, the second byte out of a 16 bit word with a mask and the appropriate bit-wise rshift.
binary 1001010111001011 hex ff00 and 8 rshift binary . <cr> 10010101 ok
The following words are made available for convenience:
\ Copyright 2020 Christopher Howard \ Licensed under the Apache License, Version 2.0 (the "License"); \ you may not use this file except in compliance with the License. \ You may obtain a copy of the License at \ http://www.apache.org/licenses/LICENSE-2.0 \ Unless required by applicable law or agreed to in writing, software \ distributed under the License is distributed on an "AS IS" BASIS, \ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \ See the License for the specific language governing permissions and \ limitations under the License. : binary 0x2 base ! ; : bit ( w n -- f ) 1 swap lshift and ; : set ( w n -- w ) 1 swap lshift or ; : clear ( w n -- w ) 1 swap lshift invert and ; : toggle ( w n -- w ) 1 swap lshift xor ; : byte0 ( w -- c ) 0xff and ; : byte1 ( w -- c ) 0xff00 and 0x8 rshift ;
binary 10010101 dup dup decimal 2 bit . 3 bit . 4 bit . <cr> 4 0 16 ok binary 10010101 decimal 2 set 3 set binary . <cr> 10011101 ok binary 10010101 decimal 2 clear 3 clear binary . <cr> 10010001 ok binary 10010101 decimal 2 toggle 3 toggle binary . <cr> 10011001 ok binary 1001010111001011 byte0 . <cr> 11001011 ok binary 1001010111001011 byte1 . <cr> 10010101 ok