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 ;
Example use:
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