Bitwise operations: Difference between revisions
J: add a minimal bit of description |
|||
Line 631: | Line 631: | ||
=={{header|J}}== |
=={{header|J}}== |
||
Here are the "bitwise operators": |
Here are the "[http://www.jsoftware.com/help/dictionary/dbdotn.htm bitwise operators]": |
||
<lang j>bAND=: 17 b. NB. 16+#.0 0 0 1 |
<lang j>bAND=: 17 b. NB. 16+#.0 0 0 1 |
Revision as of 16:47, 7 August 2011
You are encouraged to solve this task according to the task description, using any language you may know.
Basic Data Operation
This is a basic data operation. It represents a fundamental action on a basic data type.
You may see other such operations in the Basic Data Operations category, or:
Integer Operations
Arithmetic |
Comparison
Boolean Operations
Bitwise |
Logical
String Operations
Concatenation |
Interpolation |
Comparison |
Matching
Memory Operations
Pointers & references |
Addresses
Write a routine to perform a bitwise AND, OR, and XOR on two integers, a bitwise NOT on the first integer, a left shift, right shift, right arithmetic shift, left rotate, and right rotate. All shifts and rotates should be done on the first integer with a shift/rotate amount of the second integer. If any operation is not available in your language, note it.
ActionScript
ActionScript does not support bitwise rotations. <lang ActionScript>function bitwise(a:int, b:int):void { trace("And: ", a & b); trace("Or: ", a | b); trace("Xor: ", a ^ b); trace("Not: ", ~a); trace("Left Shift: ", a << b); trace("Right Shift(Arithmetic): ", a >> b); trace("Right Shift(Logical): ", a >>> b); }</lang>
Ada
The following program performs all required operations and prints the resulting values in base 2 for easy checking of the bit values.
<lang ada>with Ada.Text_Io; use Ada.Text_Io; with Interfaces; use Interfaces;
procedure Bitwise is subtype Byte is Unsigned_8; package Byte_Io is new Ada.Text_Io.Modular_Io(Byte); A : Byte := 255; B : Byte := 170; X : Byte := 128; N : Natural := 1;
begin Put_Line("A and B = "); Byte_Io.Put(Item => A and B, Base => 2); Put_Line("A or B = "); Byte_IO.Put(Item => A or B, Base => 2); Put_Line("A xor B = "); Byte_Io.Put(Item => A xor B, Base => 2); Put_Line("Not A = "); Byte_IO.Put(Item => not A, Base => 2); New_Line(2); Put_Line(Unsigned_8'Image(Shift_Left(X, N))); -- Left shift Put_Line(Unsigned_8'Image(Shift_Right(X, N))); -- Right shift Put_Line(Unsigned_8'Image(Shift_Right_Arithmetic(X, N))); -- Right Shift Arithmetic Put_Line(Unsigned_8'Image(Rotate_Left(X, N))); -- Left rotate Put_Line(Unsigned_8'Image(Rotate_Right(X, N))); -- Right rotate end bitwise;</lang>
Aikido
There is no rotate support built in to Aikido. <lang aikido>function bitwise(a, b){
println("a AND b: " + (a & b)) println("a OR b: "+ (a | b)) println("a XOR b: "+ (a ^ b)) println("NOT a: " + ~a) println("a << b: " + (a << b)) // left shift println("a >> b: " + (a >> b)) // arithmetic right shift println("a >>> b: " + (a >>> b)) // logical right shift
}</lang>
ALGOL 68
Aside from decimal, ALGOL 68 has 5 different alternative was of representing the number 170:
- 2r00000000000000000000000010101010, 4r0000000000002222, 8r00000000252, 16r000000aa
- and as an array of BOOL: FFFFFFFFFFFFFFFFFFFFFFFFTFTFTFTF
<lang algol68>main:(
PRIO SLC = 8, SRC = 8; # SLC and SRC are not built in, define and overload them here # OP SLC = (BITS b, INT rotate) BITS: b SHL rotate OR b SHR ( bits width - rotate ); OP SRC = (BITS b, INT rotate) BITS: b SHR rotate OR b SHL ( bits width - rotate ); # SRC and SRL are non-standard, but versions are built in to ALGOL 68R's standard prelude #
PRIO XOR = 2; OP XOR = (BITS p, q) BITS: p AND NOT q OR NOT p AND q; # XOR is non-standard, but a version is built in to ALGOL 68G's standard prelude #
# ALGOL 68 has 5 different ways of representing a BINary BITS - Bases: 2, 4, 8, 16 and flip/flop # FORMAT b5 = $"2r"2r32d," 4r"4r16d," 8r"8r11d," 16r"16r8d," "gl$; OP BBBBB = (BITS b)[]BITS: (b,b,b,b,b);
PROC bitwise = (BITS a, BITS b, INT shift)VOID: ( printf(( $" bits shorths: "gxgl$, bits shorths, "1 plus the number of extra SHORT BITS types", $" bits lengths: "gxgl$, bits lengths, "1 plus the number of extra LONG BITS types", $" max bits: "gl$, max bits, $" long max bits: "gl$, long max bits, $" long long max bits: "gl$, long long max bits, $" bits width: "gxgl$, bits width, "The number of CHAR required to display BITS", $" long bits width: "gxgl$, long bits width, "The number of CHAR required to display LONG BITS", $" long long bits width: "gxgl$, long long bits width, "The number of CHAR required to display LONG LONG BITS", $" bytes shorths: "gxgl$, bytes shorths, "1 plus the number of extra SHORT BYTES types", $" bytes lengths: "gxgl$, bits lengths, "1 plus the number of extra LONG BYTES types", $" bytes width: "gxgl$, bytes width, "The number of CHAR required to display BYTES", $" long bytes width: "gxgl$, long bytes width, "The number of CHAR required to display LONG BYTES" ));
printf(($" a: "f(b5)$, BBBBB a)); printf(($" b: "f(b5)$, BBBBB b)); printf(($" a AND b: "f(b5)$, BBBBB(a AND b))); printf(($" a OR b: "f(b5)$, BBBBB(a OR b))); printf(($" a XOR b: "f(b5)$, BBBBB(a XOR b))); printf(($" NOT b: "f(b5)$, BBBBB NOT a)); printf(($" a SHL "d": "f(b5)$, shift, BBBBB(a SHL shift))); printf(($" a SHR "d": "f(b5)$, shift, BBBBB(a SHR shift)));
printf(($" a SLC "d": "f(b5)$, shift, BBBBB(a SLC shift))); printf(($" a SRC "d": "f(b5)$, shift, BBBBB(a SRC shift)))
COMMENT with original ALGOL 68 character set;
printf(($" a AND b: "f(b5)$, BBBBB(a ∧ b))); printf(($" a OR b: "f(b5)$, BBBBB(a ∨ b))); printf(($" NOT b: "f(b5)$, BBBBB ¬ a)); printf(($" a SHL "d": "f(b5)$, shift, BBBBB(a ↑ shift))); printf(($" a SHR "d": "f(b5)$, shift, BBBBB(a ↓ shift)));
Also:
printf(($" a AND b: "f(b5)$, BBBBB(a /\ b))); printf(($" a OR b: "f(b5)$, BBBBB(a \/ b)));
COMMENT
);
bitwise(BIN 255, BIN 170, 5)
- or using alternate representations for 255 and 170 in BITS #
CO
bitwise(2r11111111,2r10101010,5); bitwise(4r3333,4r2222,5); bitwise(8r377,8r252,5); bitwise(16rff,16raa,5)
END CO )</lang> Output:
bits shorths: +1 1 plus the number of extra SHORT BITS types bits lengths: +3 1 plus the number of extra LONG BITS types max bits: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT long max bits: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT long long max bits: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT bits width: +32 The number of CHAR required to display BITS long bits width: +116 The number of CHAR required to display LONG BITS long long bits width: +232 The number of CHAR required to display LONG LONG BITS bytes shorths: +1 1 plus the number of extra SHORT BYTES types bytes lengths: +3 1 plus the number of extra LONG BYTES types bytes width: +32 The number of CHAR required to display BYTES long bytes width: +64 The number of CHAR required to display LONG BYTES a: 2r00000000000000000000000011111111 4r0000000000003333 8r00000000377 16r000000ff FFFFFFFFFFFFFFFFFFFFFFFFTTTTTTTT b: 2r00000000000000000000000010101010 4r0000000000002222 8r00000000252 16r000000aa FFFFFFFFFFFFFFFFFFFFFFFFTFTFTFTF a AND b: 2r00000000000000000000000010101010 4r0000000000002222 8r00000000252 16r000000aa FFFFFFFFFFFFFFFFFFFFFFFFTFTFTFTF a OR b: 2r00000000000000000000000011111111 4r0000000000003333 8r00000000377 16r000000ff FFFFFFFFFFFFFFFFFFFFFFFFTTTTTTTT a XOR b: 2r00000000000000000000000001010101 4r0000000000001111 8r00000000125 16r00000055 FFFFFFFFFFFFFFFFFFFFFFFFFTFTFTFT NOT b: 2r11111111111111111111111100000000 4r3333333333330000 8r37777777400 16rffffff00 TTTTTTTTTTTTTTTTTTTTTTTTFFFFFFFF a SHL 5: 2r00000000000000000001111111100000 4r0000000001333200 8r00000017740 16r00001fe0 FFFFFFFFFFFFFFFFFFFTTTTTTTTFFFFF a SHR 5: 2r00000000000000000000000000000111 4r0000000000000013 8r00000000007 16r00000007 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFTTT a SLC 5: 2r00000000000000000001111111100000 4r0000000001333200 8r00000017740 16r00001fe0 FFFFFFFFFFFFFFFFFFFTTTTTTTTFFFFF a SRC 5: 2r11111000000000000000000000000111 4r3320000000000013 8r37000000007 16rf8000007 TTTTTFFFFFFFFFFFFFFFFFFFFFFFFTTT
Note that an INT can be widened into BITS, and BITS can be widened into an array of BOOL. eg:
# unpack (widen) some data back into an a BOOL array # INT i := 170; BITS j := BIN i; [bits width]BOOL k := j; printf(($g", 8r"8r4d", "8(g)l$, i, j, k[bits width-8+1:])); # now pack some data back into an INT # k[bits width-8+1:] := (FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE); j := bits pack(k); i := ABS j; printf(($g", 8r"8r4d", "8(g)l$, i, j, k[bits width-8+1:]))
Output:
+170, 8r0252, TFTFTFTF +85, 8r0125, FTFTFTFT
AutoHotkey
<lang AutoHotkey>bitwise(3, 4) bitwise(a, b) {
MsgBox % "a and b: " . a & b MsgBox % "a or b: " . a | b MsgBox % "a xor b: " . a ^ b MsgBox % "not a: " . ~a ; treated as unsigned integer MsgBox % "a << b: " . a << b ; left shift MsgBox % "a >> b: " . a >> b ; arithmetic right shift
}</lang>
AWK
Standard awk does not have bitwise operators. Gawk has built-in functions for many bitwise operations. No rotation of bits.
<lang awk>BEGIN {
n = 11 p = 1 print n " or " p " = " or(n,p) print n " and " p " = " and(n,p) print n " xor " p " = " xor(n,p) print n " << " p " = " lshift(n, p) # left shift print n " >> " p " = " rshift(n, p) # right shift printf "not %d = 0x%x\n", n, compl(n) # bitwise complement
}</lang>
OpenBSD /usr/bin/awk
(a variant of nawk) has these same functions, with a few differences. Gawk uses 53-bit unsigned integers, but OpenBSD awk uses 32-bit signed integers. Therefore Gawk prints not 11 = 0x1ffffffffffff4
, but OpenBSD awk prints not 11 = 0xfffffff4
.
BASIC
QuickBasic does not have shift or rotate operations defined. Here are the logical operations: <lang qbasic>SUB bitwise (a, b)
PRINT a AND b PRINT a OR b PRINT a XOR b PRINT NOT a
END SUB</lang>
FreeBASIC does not have rotate operators. Shift Right operator performs arithmetic shift if the left value is signed number and logical shift if the left value is unsigned number. <lang freebasic>SUB bitwise (a AS Integer, b AS Integer)
DIM u AS UInteger
PRINT "a AND b = "; a AND b PRINT "a OR b = "; a OR b PRINT "a XOR b = "; a XOR b PRINT "NOT a = "; NOT a PRINT "a SHL b = "; a SHL b PRINT "a SHR b (arithmetic) = "; a SHR b u = a PRINT "a SHR b (logical) = "; u SHR b
END SUB</lang>
BBC BASIC
<lang bbcbasic> number1% = &89ABCDEF
number2% = 8 PRINT ~ number1% AND number2% : REM bitwise AND PRINT ~ number1% OR number2% : REM bitwise OR PRINT ~ number1% EOR number2% : REM bitwise exclusive-OR PRINT ~ NOT number1% : REM bitwise NOT PRINT ~ number1% << number2% : REM left shift PRINT ~ number1% >>> number2% : REM right shift (logical) PRINT ~ number1% >> number2% : REM right shift (arithmetic) PRINT ~ (number1% << number2%) OR (number1% >>> (32-number2%)) : REM left rotate PRINT ~ (number1% >>> number2%) OR (number1% << (32-number2%)) : REM right rotate</lang>
C
<lang c>void bitwise(int a, int b) {
printf("a and b: %d\n", a & b); printf("a or b: %d\n", a | b); printf("a xor b: %d\n", a ^ b); printf("not a: %d\n", ~a); printf("a << n: %d\n", a << b); /* left shift */ printf("a >> n: %d\n", a >> b); /* on most platforms: arithmetic right shift */ /* convert the signed integer into unsigned, so it will perform logical shift */ unsigned int c = a; printf("c >> b: %d\n", c >> b); /* logical right shift */ /* there are no rotation operators in C */ return 0;
}</lang>
To rotate an integer, you can combine a left shift and a right shift:
<lang C>/* rotate x to the right by s bits */
unsigned int rotr(unsigned int x, unsigned int s)
{
return (x >> s) | (x << 32 - s);
}</lang>With a smart enough compiler, the above actually compiles into a single machine bit rotate instruction when possible. E.g. gcc -S
on IA32 produced following assembly code:<lang Assembly>rotr:
movl 4(%esp), %eax ; arg1: x movl 8(%esp), %ecx ; arg2: s rorl %cl, %eax ; right rotate x by s ret</lang>
C++
<lang cpp>#include <iostream>
void bitwise(int a, int b) {
std::cout << "a and b: " << (a & b) << '\n'; // Note: parentheses are needed because & has lower precedence than << std::cout << "a or b: " << (a | b) << '\n'; std::cout << "a xor b: " << (a ^ b) << '\n'; std::cout << "not a: " << ~a << '\n'; std::cout << "a shl b: " << (a << b) << '\n'; // Note: "<<" is used both for output and for left shift std::cout << "a shr b: " << (a >> b) << '\n'; // typically arithmetic right shift, but not guaranteed unsigned int c = a; std::cout << "c sra b: " << (c >> b) << '\n'; // logical right shift (guaranteed) // there are no rotation operators in C++
}</lang>
C#
<lang csharp>static void bitwise(int a, int b)
{ Console.WriteLine("a and b is {0}", a & b); Console.WriteLine("a or b is {0}", a | b); Console.WriteLine("a xor b is {0}", a ^ b); Console.WriteLine("not a is {0}", ~a); Console.WriteLine("a lshift b is {0}", a << b); Console.WriteLine("a arshift b is {0}", a >> b); // When the left operand of the >> operator is of a signed integral type, // the operator performs an arithmetic shift right uint c = (uint)a; Console.WriteLine("c rshift b is {0}", c >> b); // When the left operand of the >> operator is of an unsigned integral type, // the operator performs a logical shift right // there are no rotation operators in C# }</lang>
Clojure
<lang lisp>(bit-and x y) (bit-or x y) (bit-xor x y) (bit-not x) (bit-shift-left x n) (bit-shift-right x n)
- There is no built-in for rotation.</lang>
Common Lisp
<lang lisp>(defun bitwise (a b)
(print (logand a b)) ; AND (print (logior a b)) ; OR ("ior" = inclusive or) (print (logxor a b)) ; XOR (print (lognot a)) ; NOT (print (ash a b)) ; arithmetic left shift (positive 2nd arg) (print (ash a (- b))) ; arithmetic right shift (negative 2nd arg) ; no logical shift
)</lang>
D
<lang d>module bitwise ; import std.stdio ;
void testbit(int a, int b) {
writefln("Input: a = %3d , b = %3d", a, b) ; writefln("AND : %8b & %08b = %032b (%4d)", a, b, a & b, a & b) ; writefln(" OR : %8b | %08b = %032b (%4d)", a, b, a | b, a | b) ; writefln("XOR : %8b ^ %08b = %032b (%4d)", a, b, a ^ b, a ^ b) ; writefln("LSH : %8b << %08b = %032b (%4d)", a, b, a << b, a << b) ; writefln("RSH : %8b >> %08b = %032b (%4d)", a, b, a >> b, a >> b) ; writefln("NOT : %8s ~ %08b = %032b (%4d)", "", a, ~a, ~a) ;
} // shift and rotation are not available void main() {
int a = 0b11111111 ; // bit literal 255 int b = 0b00000010 ; // bit literal 2 testbit(a,b) ;
}</lang>Output:
Input: a = 255 , b = 2 AND : 11111111 & 00000010 = 00000000000000000000000000000010 ( 2) OR : 11111111 | 00000010 = 00000000000000000000000011111111 ( 255) XOR : 11111111 ^ 00000010 = 00000000000000000000000011111101 ( 253) LSH : 11111111 << 00000010 = 00000000000000000000001111111100 (1020) RSH : 11111111 >> 00000010 = 00000000000000000000000000111111 ( 63) NOT : ~ 11111111 = 11111111111111111111111100000000 (-256)
Delphi
<lang Delphi>program Bitwise;
{$APPTYPE CONSOLE}
begin
Writeln('2 and 3 = ', 2 and 3); Writeln('2 or 3 = ', 2 or 3); Writeln('2 xor 3 = ', 2 xor 3); Writeln('not 2 = ', not 2); Writeln('2 shl 3 = ', 2 shl 3); Writeln('2 shr 3 = ', 2 shr 3);
// there are no built-in rotation operators in Delphi
Readln;
end.</lang>
E
E provides arbitrary-size integers, so there is no distinct arithmetic and logical shift right. E does not provide bit rotate operations.
<lang e>def bitwise(a :int, b :int) {
println(`Bitwise operations: a AND b: ${a & b} a OR b: ${a | b} a XOR b: ${a ^ b} NOT a: " + ${~a} a left shift b: ${a << b} a right shift b: ${a >> b}
`) }</lang>
F#
<lang fsharp>let bitwise a b =
printfn "a and b: %d" (a &&& b) printfn "a or b: %d" (a ||| b) printfn "a xor b: %d" (a ^^^ b) printfn "not a: %d" (~~~a) printfn "a shl b: %d" (a <<< b) printfn "a shr b: %d" (a >>> b) // arithmetic shift printfn "a shr b: %d" ((uint32 a) >>> b) // logical shift // No rotation operators.</lang>
Factor
<lang factor>"a=" "b=" [ write readln string>number ] bi@ {
[ bitand "a AND b: " write . ] [ bitor "a OR b: " write . ] [ bitxor "a XOR b: " write . ] [ drop bitnot "NOT a: " write . ] [ abs shift "a asl b: " write . ] [ neg shift "a asr b: " write . ]
} 2cleave</lang>
outputs: <lang factor>a=255 b=5 a AND b: 5 a OR b: 255 a XOR b: 250 NOT a: -256 a asl b: 8160 a asr b: 7</lang> Currently rotation and logical shifts are not implemented.
FALSE
Only AND, OR, and NOT are available. <lang false>10 3 \$@$@$@$@\ { 3 copies } "a & b = "&." a | b = "|." ~a = "%~." "</lang>
Forth
<lang forth>: arshift 0 ?do 2/ loop ; \ 2/ is an arithmetic shift right by one bit (2* shifts left one bit)
- bitwise ( a b -- )
cr ." a = " over . ." b = " dup . cr ." a and b = " 2dup and . cr ." a or b = " 2dup or . cr ." a xor b = " 2dup xor . cr ." not a = " over invert . cr ." a shl b = " 2dup lshift . cr ." a shr b = " 2dup rshift . cr ." a ashr b = " 2dup arshift . 2drop ;</lang>
Rotation is not standard, but may be provided in particular Forth implementations, or as an assembly instruction in CODE words.
Fortran
In ISO Fortran 90 and later the following BIT INTRINSIC functions are defined: <lang fortran>integer :: i, j = -1, k = 42 logical :: a
i = bit_size(j) ! returns the number of bits in the given INTEGER variable
! bitwise boolean operations on integers i = iand(k, j) ! returns bitwise AND of K and J i = ior(k, j) ! returns bitwise OR of K and J i = ieor(k, j) ! returns bitwise EXCLUSIVE OR of K and J i = not(j) ! returns bitwise NOT of J
! single-bit integer/logical operations (bit positions are zero-based) a = btest(i, 4) ! returns logical .TRUE. if bit position 4 of I is 1, .FALSE. if 0 i = ibclr(k, 8) ! returns value of K with 8th bit position "cleared" (set to 0) i = ibset(k, 13) ! returns value of K with 13th bit position "set" (set to 1)
! multi-bit integer operations i = ishft(k, j) ! returns value of K shifted by J bit positions, with ZERO fill
! (right shift if J < 0 and left shift if J > 0).
i = ishftc(k, j) ! returns value of K shifted CIRCULARLY by J bit positions
! (right circular shift if J < 0 and left if J > 0)
i = ishftc(k, j, 20) ! returns value as before except that ONLY the 20 lowest order
! (rightmost) bits are circularly shifted
i = ibits(k, 7, 8) ! extracts 8 contiguous bits from K starting at position 7 and
! returns them as the rightmost bits of an otherwise ! zero-filled integer. For non-negative K this is ! arithmetically equivalent to: MOD((K / 2**7), 2**8)</lang>
The following INTRINSIC ELEMENTAL SUBROUTINE is also defined: <lang fortran> call mvbits(k, 2, 4, j, 0) ! copy a sequence of 4 bits from k starting at bit 2 into j starting at bit 0</lang>
Go
<lang go>package main
import "fmt"
func bitwise(a, b int16) (and, or, xor, not, shl, shr, ras, rol, ror int16) {
// the first four are easy and = a & b or = a | b xor = a ^ b not = ^a
// for all shifts, the right operand (shift distance) must be unsigned. // use abs(b) for a non-negative value. if b < 0 { b = -b } ub := uint(b)
shl = a << ub // for right shifts, if the left operand is unsigned, Go performs // a logical shift; if signed, an arithmetic shift. shr = int16(uint16(a) >> ub) ras = a >> ub
// rotates rol = a << ub | int16(uint16(a) >> (16-ub)) ror = int16(uint16(a) >> ub) | a << (16-ub) return
}
func main() {
var a, b int16 = -460, 6 and, or, xor, not, shl, shr, ras, rol, ror := bitwise(a, b) fmt.Printf("a: %016b\n", uint16(a)) fmt.Printf("b: %016b\n", uint16(b)) fmt.Printf("and: %016b\n", uint16(and)) fmt.Printf("or: %016b\n", uint16(or)) fmt.Printf("xor: %016b\n", uint16(xor)) fmt.Printf("not: %016b\n", uint16(not)) fmt.Printf("shl: %016b\n", uint16(shl)) fmt.Printf("shr: %016b\n", uint16(shr)) fmt.Printf("ras: %016b\n", uint16(ras)) fmt.Printf("rol: %016b\n", uint16(rol)) fmt.Printf("ror: %016b\n", uint16(ror))
}</lang> Output:
a: 1111111000110100 b: 0000000000000110 and: 0000000000000100 or: 1111111000110110 xor: 1111111000110010 not: 0000000111001011 shl: 1000110100000000 shr: 0000001111111000 ras: 1111111111111000 rol: 1000110100111111 ror: 1101001111111000
Groovy
<lang groovy>def bitwise = { a, b ->
println """
a & b = ${a} & ${b} = ${a & b} a | b = ${a} | ${b} = ${a | b} a ^ b = ${a} ^ ${b} = ${a ^ b} ~ a = ~ ${a} = ${~ a} a << b = ${a} << ${b} = ${a << b} a >> b = ${a} >> ${b} = ${a >> b} arithmetic (sign-preserving) shift a >>> b = ${a} >>> ${b} = ${a >>> b} logical (zero-filling) shift """ }</lang>
Program: <lang groovy>bitwise(-15,3)</lang>
Output:
a & b = -15 & 3 = 1 a | b = -15 | 3 = -13 a ^ b = -15 ^ 3 = -14 ~ a = ~ -15 = 14 a << b = -15 << 3 = -120 a >> b = -15 >> 3 = -2 arithmetic (sign-preserving) shift a >>> b = -15 >>> 3 = 536870910 logical (zero-filling) shift
Haskell
The operations in Data.Bits work on Int, Integer, and any of the sized integer and word types. <lang haskell>import Data.Bits
bitwise :: Int -> Int -> IO () bitwise a b = do
print $ a .&. b print $ a .|. b print $ a `xor` b print $ complement a print $ shiftL a b -- left shift print $ shiftR a b -- arithmetic right shift print $ shift a b -- You can also use the "unified" shift function; positive is for left shift, negative is for right shift print $ shift a (-b) print $ rotateL a b -- rotate left print $ rotateR a b -- rotate right print $ rotate a b -- You can also use the "unified" rotate function; positive is for left rotate, negative is for right rotate print $ rotate a (-b)
main = bitwise 255 170</lang> If you were shifting Words (unsigned integers) instead of Ints, then the shift would be automatically logical shifts:
import Data.Word print $ shiftL (-1 :: Word) 1 print $ shiftR (-1 :: Word) 1
HicEst
There is no rotate and no shift support built in to HicEst <lang hicest>i = IAND(k, j) i = IOR( k, j) i = IEOR(k, j) i = NOT( k )</lang>
Icon and Unicon
<lang Icon>procedure main() bitdemo(255,2) bitdemo(-15,3) end
procedure bitdemo(i,i2)
write() demowrite("i",i) demowrite("i2",i2) demowrite("complement i",icom(i)) demowrite("i or i2",ior(i,i2)) demowrite("i and i2",iand(i,i2)) demowrite("i xor i2",ixor(i,i2)) demowrite("i shift " || i2,ishift(i,i2)) demowrite("i shift -" || i2,ishift(i,-i2)) return
end
procedure demowrite(vs,v) return write(vs, ": ", v, " = ", int2bit(v),"b") end</lang>
Icon/Unicon implements bitwise operations on integers. Because integers can be transparently large integers operations that require fixed sizes don't make sense and aren't defined. These include rotation and logical shifting (shift is arithmetic) . Please note also that 'not' is a reserved word and the negation function is 'icom'
Sample output:
i: 255 = 11111111b i2: 2 = 10b complement i: -256 = -100000000b i or i2: 255 = 11111111b i and i2: 2 = 10b i xor i2: 253 = 11111101b i shift 2: 1020 = 1111111100b i shift -2: 63 = 111111b i: -15 = -1111b i2: 3 = 11b complement i: 14 = 1110b i or i2: -13 = -1101b i and i2: 1 = 1b i xor i2: -14 = -1110b i shift 3: -120 = -1111000b i shift -3: -2 = -10b
J
Here are the "bitwise operators":
<lang j>bAND=: 17 b. NB. 16+#.0 0 0 1 bOR=: 23 b. NB. 16+#.0 1 1 1 bXOR=: 22 b. NB. 16+#.0 1 1 0 b1NOT=: 28 b. NB. 16+#.1 1 0 0 bLshift=: 33 b.~ NB. see http://www.jsoftware.com/help/release/bdot.htm bRshift=: 33 b.~ - bRAshift=: 34 b.~ - bLrot=: 32 b.~ bRrot=: 32 b.~ -</lang>
And here is a routine which takes a list of bitwise operators and two numbers and displays a table of results from combining those two numbers with each of the operators:
<lang j>bitwise=: 1 :0
smoutput (((":x),"1' ',.(>u),.' '),"1":y),"1' => ',"1'.X'{~#:x u`:0 y
)</lang>
And here they are in action:
<lang j> 254 bAND`bOR`bXOR`b1NOT`bLshift`bRshift`bRAshift`bLrot`bRrot bitwise 3 254 bAND 3 => ............................X. 254 bOR 3 => ......................XXXXXXXX 254 bXOR 3 => ......................XXXXXX.X 254 b1NOT 3 => XXXXXXXXXXXXXXXXXXXXXX.......X 254 bLshift 3 => ...................XXXXXXX.... 254 bRshift 3 => .........................XXXXX 254 bRAshift 3 => .........................XXXXX 254 bLrot 3 => ...................XXXXXXX.... 254 bRrot 3 => .........................XXXXX</lang>
Java
<lang java>public static void bitwise(int a, int b){
System.out.println("a AND b: " + (a & b)); System.out.println("a OR b: "+ (a | b)); System.out.println("a XOR b: "+ (a ^ b)); System.out.println("NOT a: " + ~a); System.out.println("a << b: " + (a << b)); // left shift System.out.println("a >> b: " + (a >> b)); // arithmetic right shift System.out.println("a >>> b: " + (a >>> b)); // logical right shift System.out.println("a rol b: " + Integer.rotateLeft(a, b)); //rotate left System.out.println("a ror b: " + Integer.rotateRight(a, b)); //rotate right
}</lang> All of these operations may be combined with the = operator to save space. For example, the following lines each do the same thing: <lang java>a <<= 3; a = a << 3; a *= 8; //2 * 2 * 2 = 8 a = a * 8;</lang>
JavaScript
<lang javascript>function bitwise(a, b){
alert("a AND b: " + (a & b)); alert("a OR b: "+ (a | b)); alert("a XOR b: "+ (a ^ b)); alert("NOT a: " + ~a); alert("a << b: " + (a << b)); // left shift alert("a >> b: " + (a >> b)); // arithmetic right shift alert("a >>> b: " + (a >>> b)); // logical right shift
}</lang>
Liberty BASIC
Written as functions. <lang lb> ' bitwise operations on byte-sized variables
v =int( 256 *rnd( 1))
s = 1
print "Shift ="; s; " place." print print "Number as dec. = "; v; " & as 8-bits byte = ", dec2Bin$( v) print "NOT as dec. = "; bitInvert( v), dec2Bin$( bitInvert( v)) print "Shifted left as dec. = "; shiftLeft( v, s), dec2Bin$( shiftLeft( v, s)) print "Shifted right as dec. = "; shiftRight( v, s), dec2Bin$( shiftRight( v, s)) print "Rotated left as dec. = "; rotateLeft( v, s), dec2Bin$( rotateLeft( v, s)) print "Rotated right as dec. = "; rotateRight( v, s), dec2Bin$( rotateRight( v, s))
end
function shiftLeft( b, n)
shiftLeft =( b *2^n) and 255
end function
function shiftRight( b, n)
shiftRight =int(b /2^n)
end function
function rotateLeft( b, n)
rotateLeft = (( 2^n *b) mod 256) or ( b >127)
end function
function rotateRight( b, n)
rotateRight = (128*( b and 1)) or int( b /2)
end function
function bitInvert( b)
bitInvert =b xor 255
end function
function dec2Bin$( num) ' Given an integer decimal 0 <--> 255, returns binary equivalent as a string
n =num dec2Bin$ ="" while ( num >0) dec2Bin$ =str$( num mod 2) +dec2Bin$ num =int( num /2) wend dec2Bin$ =right$( "00000000" +dec2Bin$, 8)
end function </lang>
LLVM
<lang llvm>; ModuleID = 'test.o'
- e means little endian
- p
- { pointer size : pointer abi : preferred alignment for pointers }
- i same for integers
- v is for vectors
- f for floats
- a for aggregate types
- s for stack objects
- n
- {size:size:size...}, best integer sizes
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
- this was compiled with mingw32; thus it must be linked to an ABI compatible c library
target triple = "i386-mingw32"
@.str = private constant [13 x i8] c"a and b: %d\0A\00", align 1 ; <[13 x i8]*> [#uses=1] @.str1 = private constant [12 x i8] c"a or b: %d\0A\00", align 1 ; <[12 x i8]*> [#uses=1] @.str2 = private constant [13 x i8] c"a xor b: %d\0A\00", align 1 ; <[13 x i8]*> [#uses=1] @.str3 = private constant [11 x i8] c"not a: %d\0A\00", align 1 ; <[11 x i8]*> [#uses=1] @.str4 = private constant [12 x i8] c"a << n: %d\0A\00", align 1 ; <[12 x i8]*> [#uses=1] @.str5 = private constant [12 x i8] c"a >> n: %d\0A\00", align 1 ; <[12 x i8]*> [#uses=1] @.str6 = private constant [12 x i8] c"c >> b: %d\0A\00", align 1 ; <[12 x i8]*> [#uses=1]
- A function that will do many bitwise opreations to two integer arguments, %a and %b
define void @bitwise(i32 %a, i32 %b) nounwind {
- entry block
entry:
;Register to store (a & b) %0 = and i32 %b, %a ; <i32> [#uses=1] ;print the results %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0), i32 %0) nounwind ; <i32> [#uses=0] ;Register to store (a | b) %2 = or i32 %b, %a ; <i32> [#uses=1] ;print the results %3 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str1, i32 0, i32 0), i32 %2) nounwind ; <i32> [#uses=0] ;Register to store (a ^ b) %4 = xor i32 %b, %a ; <i32> [#uses=1] ;print the results %5 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str2, i32 0, i32 0), i32 %4) nounwind ; <i32> [#uses=0] ;Register to store (~a) %not = xor i32 %a, -1 ; <i32> [#uses=1] ;print the results %6 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.str3, i32 0, i32 0), i32 %not) nounwind ; <i32> [#uses=0] ;Register to store (a << b) %7 = shl i32 %a, %b ; <i32> [#uses=1] ;print the results %8 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str4, i32 0, i32 0), i32 %7) nounwind ; <i32> [#uses=0] ;Register to store (a >> b) (a is signed) %9 = ashr i32 %a, %b ; <i32> [#uses=1] ;print the results %10 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str5, i32 0, i32 0), i32 %9) nounwind ; <i32> [#uses=0] ;Register to store (c >> b), where c is unsiged (eg. logical right shift) %11 = lshr i32 %a, %b ; <i32> [#uses=1] ;print the results %12 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str6, i32 0, i32 0), i32 %11) nounwind ; <i32> [#uses=0] ;terminator instruction ret void
}
- Declare external fuctions
declare i32 @printf(i8* nocapture, ...) nounwind</lang>
Logo
<lang logo>to bitwise :a :b
(print [a and b:] BitAnd :a :b) (print [a or b:] BitOr :a :b) (print [a xor b:] BitXor :a :b) (print [not a:] BitNot :a) ; shifts are to the left if positive, to the right if negative (print [a lshift b:] LShift :a :b) (print [a lshift -b:] LShift :a minus :b) (print [-a ashift -b:] AShift minus :a minus :b)
end bitwise 255 5</lang> The output of this program is: <lang logo>a and b: 5 a or b: 255 a xor b: 250 not a: -256 a lshift b: 8160 a lshift -b: 7 -a ashift -b: -8</lang>
Lua
LuaBitOp implements bitwise functionality for Lua:
<lang lua>local bit = require"bit"
local vb = {
0, 1, -1, 2, -2, 0x12345678, 0x87654321, 0x33333333, 0x77777777, 0x55aa55aa, 0xaa55aa55, 0x7fffffff, 0x80000000, 0xffffffff
}
local function cksum(name, s, r)
local z = 0 for i=1,#s do z = (z + string.byte(s, i)*i) % 2147483629 end if z ~= r then error("bit."..name.." test failed (got "..z..", expected "..r..")", 0) end
end
local function check_unop(name, r)
local f = bit[name] local s = "" if pcall(f) or pcall(f, "z") or pcall(f, true) then error("bit."..name.." fails to detect argument errors", 0) end for _,x in ipairs(vb) do s = s..","..tostring(f(x)) end cksum(name, s, r)
end
local function check_binop(name, r)
local f = bit[name] local s = "" if pcall(f) or pcall(f, "z") or pcall(f, true) then error("bit."..name.." fails to detect argument errors", 0) end for _,x in ipairs(vb) do for _,y in ipairs(vb) do s = s..","..tostring(f(x, y)) end end cksum(name, s, r)
end
local function check_binop_range(name, r, yb, ye)
local f = bit[name] local s = "" if pcall(f) or pcall(f, "z") or pcall(f, true) or pcall(f, 1, true) then error("bit."..name.." fails to detect argument errors", 0) end for _,x in ipairs(vb) do for y=yb,ye do s = s..","..tostring(f(x, y)) end end cksum(name, s, r)
end
local function check_shift(name, r)
check_binop_range(name, r, 0, 31)
end
-- Minimal sanity checks. assert(0x7fffffff == 2147483647, "broken hex literals") assert(0xffffffff == -1 or 0xffffffff == 2^32-1, "broken hex literals") assert(tostring(-1) == "-1", "broken tostring()") assert(tostring(0xffffffff) == "-1" or tostring(0xffffffff) == "4294967295", "broken tostring()")
-- Basic argument processing. assert(bit.tobit(1) == 1) assert(bit.band(1) == 1) assert(bit.bxor(1,2) == 3) assert(bit.bor(1,2,4,8,16,32,64,128) == 255)</lang>
LSE64
<lang lse64>over : 2 pick 2dup : over over
bitwise : \
" A=" ,t over ,h sp " B=" ,t dup ,h nl \ " A and B=" ,t 2dup & ,h nl \ " A or B=" ,t 2dup | ,h nl \ " A xor B=" ,t over ^ ,h nl \ " not A=" ,t ~ ,h nl
\ a \ 7 bitwise # hex literals</lang>
Mathematica
Most functions are built-in or can be made really easily: <lang Mathematica>(*and xor and or*) BitAnd[integer1, integer2] BitXor[integer1, integer2] BitOr[integer1, integer2]
(*logical not*) BitNot[integer1]
(*left and right shift*) BitShiftLeft[integer1] BitShiftRight[integer1]
(*rotate digits left and right*) FromDigits[RotateLeft[IntegerDigits[integer1, 2]], 2] FromDigits[RotateRight[IntegerDigits[integer1, 2]], 2]
(*right arithmetic shift*) FromDigits[Prepend[Most[#], #1], 2] &[IntegerDigits[integer1, 2]]</lang> The function BitShiftLeft, BitShiftRight, RotateRight, RotateLeft all take a second argument, which is the displacement, by default it is set to 1. BitAnd, BitXor and BitOr can handle more than 2 arguments: <lang Mathematica>BitXor[3333, 5555, 7777, 9999]</lang> gives back: <lang Mathematica>8664</lang>
MATLAB
Newer versions of MATLAB have even more bitwise operations than those demonstrated here. A complete list of bitwise operations for the newest version of MATLAB can be found at MathWorks
<lang MATLAB>function bitwiseOps(a,b)
disp(sprintf('%d and %d = %d', [a b bitand(a,b)])); disp(sprintf('%d or %d = %d', [a b bitor(a,b)])); disp(sprintf('%d xor %d = %d', [a b bitxor(a,b)])); disp(sprintf('%d << %d = %d', [a b bitshift(a,b)])); disp(sprintf('%d >> %d = %d', [a b bitshift(a,-b)]));
end</lang>
Output: <lang MATLAB>>> bitwiseOps(255,2) 255 and 2 = 2 255 or 2 = 255 255 xor 2 = 253 255 << 2 = 1020 255 >> 2 = 63</lang>
MAXScript
<lang maxscript>fn bitwise a b = (
format "a and b: %\n" (bit.and a b) format "a or b: %\n" (bit.or a b) format "a xor b: %\n" (bit.xor a b) format "not a: %\n" (bit.not a) format "Left shift a: %\n" (bit.shift a b) format "Right shift a: %\n" (bit.shift a -b)
)
bitwise 255 170</lang>
MAXScript doesn't have arithmetic shift or rotate operations.
Modula-3
<lang modula3>MODULE Bitwise EXPORTS Main;
IMPORT IO, Fmt, Word;
VAR c: Word.T;
PROCEDURE Bitwise(a, b: INTEGER) =
BEGIN IO.Put("a AND b: " & Fmt.Int(Word.And(a, b)) & "\n"); IO.Put("a OR b: " & Fmt.Int(Word.Or(a, b)) & "\n"); IO.Put("a XOR b: " & Fmt.Int(Word.Xor(a, b)) & "\n"); IO.Put("NOT a: " & Fmt.Int(Word.Not(a)) & "\n"); c := a; IO.Put("c LeftShift b: " & Fmt.Unsigned(Word.LeftShift(c, b)) & "\n"); IO.Put("c RightShift b: " & Fmt.Unsigned(Word.RightShift(c, b)) & "\n"); IO.Put("c LeftRotate b: " & Fmt.Unsigned(Word.LeftRotate(c, b)) & "\n"); IO.Put("c RightRotate b: " & Fmt.Unsigned(Word.RightRotate(c, b)) & "\n"); END Bitwise;
BEGIN
Bitwise(255, 5);
END Bitwise.</lang>
Output:
a AND b: 5 a OR b: 255 a XOR b: 250 NOT a: -256 c LeftShift b: 1fe0 c RightShift b: 7 c LeftRotate b: 1fe0 c RightRotate b: f8000007
Nemerle
<lang Nemerle>def i = 255; def j = 2;
WriteLine($"$i and $j is $(i & j)"); WriteLine($"$i or $j is $(i | j)"); WriteLine($"$i xor $j is $(i ^ j)"); WriteLine($"not $i is $(~i)"); WriteLine($"$i lshift $j is $(i << j)"); WriteLine($"$i arshift $j is $(i >> j)"); // When the left operand of the >> operator is of a signed integral type,
// the operator performs an arithmetic shift right
WriteLine($"$(i :> uint) rshift $j is $(c >> j)"); // When the left operand of the >> operator is of an unsigned integral type,
// the operator performs a logical shift right
// there are no rotation operators in Nemerle, but you could define your own w/ a macro if you really wanted it</lang>
NSIS
All bitwise operations in NSIS are handled by the IntOp instruction. <lang nsis>Function Bitwise Push $0 Push $1 Push $2 StrCpy $0 7 StrCpy $1 2
IntOp $2 $0 & $1 DetailPrint "Bitwise AND: $0 & $1 = $2" IntOp $2 $0 | $1 DetailPrint "Bitwise OR: $0 | $1 = $2" IntOp $2 $0 ^ $1 DetailPrint "Bitwise XOR: $0 ^ $1 = $2" IntOp $2 $0 ~ DetailPrint "Bitwise NOT (negate in NSIS docs): ~$0 = $2" DetailPrint "There are no Arithmetic shifts in NSIS" IntOp $2 $0 >> $1 DetailPrint "Right Shift: $0 >> 1 = $2" IntOp $2 $0 << $1 DetailPrint "Left Shift: $0 << $1 = $2" DetailPrint "There are no Rotates in NSIS"
Pop $2
Pop $1
Pop $0
FunctionEnd</lang>
Objeck
<lang objeck>use IO;
bundle Default {
class Test { function : Main(args : String[]) ~ Nil { BitWise(3, 4); }
function : BitWise(a : Int, b : Int) ~ Nil { Console->GetInstance()->Print("a and b: ")->PrintLine(a and b); Console->GetInstance()->Print("a or b: ")->PrintLine(a or b); Console->GetInstance()->Print("a xor b: ")->PrintLine(a xor b); # shift left & right are supported by the compiler and VM but not # exposed to end-users; those instructions are used for optimizations } }
}</lang>
OCaml
<lang ocaml>let bitwise a b =
Printf.printf "a and b: %d\n" (a land b); Printf.printf "a or b: %d\n" (a lor b); Printf.printf "a xor b: %d\n" (a lxor b); Printf.printf "not a: %d\n" (lnot a); Printf.printf "a lsl b: %d\n" (a lsl b); (* left shift *) Printf.printf "a asr b: %d\n" (a asr b); (* arithmetic right shift *) Printf.printf "a lsr b: %d\n" (a lsr b); (* logical right shift *)
- </lang>
Octave
There's no arithmetic shift nor rotation (and the not can be done through a xor)
<lang octave>function bitops(a, b)
s = sprintf("%s %%s %s = %%s\n", dec2bin(a), dec2bin(b)); printf(s, "or", dec2bin(bitor(a, b))); printf(s, "and", dec2bin(bitand(a, b))); printf(s, "xor", dec2bin(bitxor(a, b))); printf(s, "left shift", dec2bin(bitshift(a, abs(b)))); printf(s, "right shift", dec2bin(bitshift(a, -abs(b)))); printf("simul not %s = %s", dec2bin(a), dec2bin(bitxor(a, 0xffffffff)));
endfunction
bitops(0x1e, 0x3);</lang>
PARI/GP
Pari does not support bitwise rotations, which have no obvious meaning with arbitrary-precision integers. See also bitnegimply
for another bitwise operator. For shifts, see also shiftmul
.
<lang parigp>bo(a,b)={
print("And: "bitand(a,b)); print("Or: "bitor(a,b)); print("Not: "bitneg(a)); print("Xor: "bitxor(a,b)); print("Left shift: ",a<<b); print("Right shift: ",a>>b);
}</lang>
Pascal
While Standard Pascal does not have bitwise operations, most Pascal implementations (including Turbo Pascal and Delphi) extend the standard logical operators to also provide bitwise operations: <lang pascal>var
a, b: integer;
begin
a := 10; { binary 1010 } b := 12; { binary 1100 } writeln('a and b = ', a and b); { 8 = 1000 } writeln('a or b = ', a or b); { 14 = 1110 } writeln('a xor b = ', a xor b) { 6 = 0110 }
end.</lang>
Perl
<lang perl>use integer;
sub bitwise($$) {
($a, $b) = @_; print 'a and b: '. ($a & $b) ."\n"; print 'a or b: '. ($a | $b) ."\n"; print 'a xor b: '. ($a ^ $b) ."\n"; print 'not a: '. (~$a) ."\n"; print 'a >> b: ', $a >> $b, "\n"; # logical right shift
use integer; # "use integer" enables bitwise operations to return signed ints print "after use integer:\n"; print 'a << b: ', $a << $b, "\n"; # left shift print 'a >> b: ', $a >> $b, "\n"; # arithmetic right shift
}</lang>
Perl 6
Bitwise operations in Perl 6 are separated into boolean, buffer and interger contexts. Boolean operators coerce their arguments to booleans and return a boolean value. Buffer bitwise operators coerce to string buffers and return a buffer. Integer bitwise operators coerce their arguments to integers and return an integer value.
<lang perl6>sub bool ($a, $b) {
say 'Coerce to Boolean'; say_bool_buff "$a and $b", $a ?& $b; say_bool_buff "$a or $b", $a ?| $b; say_bool_buff "$a xor $b", $a ?^ $b; say_bool_buff "not $a", !$a;
}
sub buf ($a, $b) {
say 'Coerce to Buffer'; say_bool_buff "$a and $b", $a ~& $b; say_bool_buff "$a or $b", $a ~| $b; say_bool_buff "$a xor $b", $a ~^ $b;
- say_bool_buff "$a bit shift right $b", $a ~> $b; #NYI in Rakudo
- say_bool_buff "$a bit shift left $b", $a ~< $b; #NYI in Rakudo
}
sub int ($a, $b) {
say 'Coerce to Int'; say_bit "$a and $b", $a +& $b; say_bit "$a or $b", $a +| $b; say_bit "$a xor $b", $a +^ $b; say_bit "$a signed bit shift right $b", $a +> $b;
- say_bit "$a unsigned bit shift right $b", $a +> $b :unsigned; #NYI in Rakudo
- say_bit "$a rotate right $b", $a +> $b :rotate; #NYI in Rakudo
say_bit "$a bit shift left $b", $a +< $b;
- say_bit "$a rotate shift left $b", $a +< $b :rotate; #NYI in Rakudo
say_bit "twos complement not $a", +^$a;
}
bool(7,2); say '-' x 80; buf(7,2); say '-' x 80; int(7,2); say '-' x 80;
sub say_bit ($message, $value) {
my $INTSIZE = $*VM{'config'}{'intvalsize'} * 8; # hack to get native Int size printf("%30s: %4d, %032b\n", $message, $value, $value) if $INTSIZE == 32; printf("%30s: %4d, %064b\n", $message, $value, $value) if $INTSIZE == 64;
}
sub say_bool_buff ($message, $value) {
printf("%30s: %4d, %s\n", $message, $value, $value);
}</lang>
The integer bitwise unsigned shift and rotate operators have not been implemented
yet since Rakudo is still getting big integer support firmed up, and does not yet
parse adverbs in infix operators. Here are some possible implementations that use
native sized integers. (Rakudo on Parrot only!)
<lang perl6>sub infix:<bsr>( $a, $b, :$rotate, :$unsigned ) {
if $rotate { my $INTSIZE = $*VM{'config'}{'intvalsize'} * 8; # hack to get native Int size my $c = $b % $INTSIZE; return pir::lsr__III($a, $c) +| pir::shl__III((2**$c-1) +& $a, $INTSIZE-$c); } if $unsigned { return pir::lsr__III($a, $b); } pir::shr__III($a, $b);
}
sub infix:<bsl>( $a, $b, :$rotate, :$unsigned ) {
if $rotate { my $INTSIZE = $*VM{'config'}{'intvalsize'} * 8; # hack to get native Int size my $c = $b % $INTSIZE; return pir::shl__III($a, $c) +| pir::lsr__III($a, $INTSIZE-$c); } pir::shl__III($a, $b);
}
bs_int(7,2);
sub bs_int ($a, $b) {
say_bit "$a Signed Bit shift right $b", $a bsr $b; say_bit "$a Unsigned Bit shift right $b", infix:<bsr>($a, $b, :unsigned); say_bit "$a Rotate right $b", infix:<bsr>($a, $b, :rotate); say_bit "$a Bit shift left $b", $a bsl $b; say_bit "$a Rotate left $b", infix:<bsl>($a, $b, :rotate);
}</lang>
PHP
<lang php>function bitwise($a, $b) {
echo '$a AND $b: ', $a & $b, "\n"; echo '$a OR $b: ', $a | $b, "\n"; echo '$a XOR $b: ', $a ^ $b, "\n"; echo 'NOT $a: ', ~$a, "\n"; echo '$a << $b: ', $a << $b, "\n"; // left shift echo '$a >> $b: ', $a >> $b, "\n"; // arithmetic right shift
}</lang>
PicoLisp
PicoLisp has no specific word size. Numbers grow to arbitrary length. Therefore, bitwise NOT, logical (non-arithmetic) SHIFTs, and rotate operations do not make sense.
Bitwise AND: <lang PicoLisp>: (& 6 3) -> 2
- (& 7 3 1)
-> 1</lang> Bitwise AND-Test (tests if all bits in the first argument are set in the following arguments): <lang PicoLisp>: (bit? 1 2) -> NIL
- (bit? 6 3)
-> NIL
- (bit? 6 15 255)
-> 6</lang> Bitwise OR: <lang PicoLisp>: (| 1 2) -> 3
- (| 1 2 4 8)
-> 15</lang> Bitwise XOR: <lang PicoLisp>: (x| 2 7) -> 5
- (x| 2 7 1)
-> 4</lang> Shift (right with a positive count, left with a negative count): <lang PicoLisp>: (>> 1 8) -> 4
- (>> 3 16)
-> 2
- (>> -3 16)
-> 128
- (>> -1 -16)
-> -32</lang>
PL/I
<lang PL/I> /* PL/I can perform bit operations on binary integers. */ k = iand(i,j); k = ior(i,j); k = inot(i,j); k = ieor(i,j); k = ishl(i,n); /* unsigned shifts i left by n places. */ k = ishr(i,n); /* unsigned shifts i right by n places. */ k = lower2(i, n); /* arithmetic right shift i by n places. */ k = raise2(i, n); /* arithmetic left shift i by n places. */
/* PL/I can also perform boolean operations on bit strings */ /* of any length: */
declare (s, t, u) bit (*);
u = s & t; /* logical and */ u = s | t; /* logical or */ u = ^ s; /* logical not */ u = s ^ t; /* exclusive or */ </lang>
Pop11
<lang pop11>define bitwise(a, b);
printf(a && b, 'a and b = %p\n'); printf(a || b, 'a or b = %p\n'); printf(a ||/& b, 'a xor b = %p\n'); printf(~~ a, 'not a = %p\n'); printf(a << b, 'left shift of a by b = %p\n'); printf(a >> b, 'arithmetic right shift of a by b = %p\n');
enddefine;</lang>
Conceptually in Pop11 integers have infinite precision, in particular negative numbers conceptually have infinitely many leading 1's in two's complement notation. Hence, logical right shift is not defined. If needed, logical right shift can be simulated by masking high order bits.
Similarly, on infinitely precise numbers rotation is undefined.
PureBasic
<lang PureBasic>Procedure Bitwise(a, b)
Debug a & b ; And Debug a | b ;Or Debug a ! b ; XOr Debug ~a ;Not Debug a << b ; shift left Debug a >> b ; arithmetic shift right ; Logical shift right and rotates are not available ; You can of use inline ASM to achieve this: Define Temp ; logical shift right !mov edx, dword [p.v_a] !mov ecx, dword [p.v_b] !shr edx, cl !mov dword [p.v_Temp], edx Debug Temp ; rotate left !mov edx, dword [p.v_a] !mov ecx, dword [p.v_b] !rol edx, cl !mov dword [p.v_Temp], edx Debug Temp ; rotate right !mov edx, dword [p.v_a] !mov ecx, dword [p.v_b] !ror edx, cl !mov dword [p.v_Temp], edx Debug Temp
EndProcedure</lang>
Python
<lang python>def bitwise(a, b):
print 'a and b:', a & b print 'a or b:', a | b print 'a xor b:', a ^ b print 'not a:', ~a print 'a << b:', a << b # left shift print 'a >> b:', a >> b # arithmetic right shift</lang>
Python does not have built in rotate or logical right shift operations.
Note: Newer Python versions (circa 2.4?) will automatically promote integers into "long integers" (arbitrary length, bounded by available memory). This can be noticed especially when using left shift operations. When using bitwise operations one usually wants to keep these bounded to specific sizes such as 8, 16, 32 or 64 bit widths. To do these we use the AND operator with specific values (bitmasks). For example:
<lang python># 8-bit bounded shift: x = x << n & 0xff
- ditto for 16 bit:
x = x << n & 0xffff
- ... and 32-bit:
x = x << n & 0xffffffff
- ... and 64-bit:
x = x << n & 0xffffffffffffffff</lang>
We can easily implement our own rotation functions. For left rotations this is down by ORing the left shifted and masked lower bits against the right shifted upper bits. For right rotations we perform the converse operations, ORing a set of right shifted lower bits against the appropriate number of left shifted upper bits.
<lang python>def bitstr(n, width=None):
"""return the binary representation of n as a string and optionally zero-fill (pad) it to a given length """ result = list() while n: result.append(str(n%2)) n = int(n/2) if (width is not None) and len(result) < width: result.extend(['0'] * (width - len(result))) result.reverse() return .join(result)
def mask(n):
"""Return a bitmask of length n (suitable for masking against an int to coerce the size to a given length) """ if n >= 0: return 2**n - 1 else: return 0
def rol(n, rotations=1, width=8):
"""Return a given number of bitwise left rotations of an integer n, for a given bit field width. """ rotations %= width if rotations < 1: return n n &= mask(width) ## Should it be an error to truncate here? return ((n << rotations) & mask(width)) | (n >> (width - rotations))
def ror(n, rotations=1, width=8):
"""Return a given number of bitwise right rotations of an integer n, for a given bit field width. """ rotations %= width if rotations < 1: return n n &= mask(width) return (n >> rotations) | ((n << (width - rotations)) & mask(width))</lang>
In this example we show a relatively straightforward function for converting integers into strings of bits, and another simple mask() function to create arbitrary lengths of bits against which we perform our masking operations. Also note that the implementation of these functions defaults to single bit rotations of 8-bit bytes. Additional arguments can be used to over-ride these defaults. Any case where the number of rotations modulo the width is zero represents a rotation of all bits back to their starting positions. This implementation should handle any integer number of rotations over bitfields of any valid (positive integer) length.
R
The logical operators in R, namely &, | and !, are designed to work on logical vectors rather than bits. It is possible to convert from integer to logical vector and back to make these work as required, e.g. <lang R>intToLogicalBits <- function(intx) as.logical(intToBits(intx)) logicalBitsToInt <- function(lb) as.integer(sum((2^(0:31))[lb])) "%AND%" <- function(x, y) {
logicalBitsToInt(intToLogicalBits(x) & intToLogicalBits(y))
} "%OR%" <- function(x, y) {
logicalBitsToInt(intToLogicalBits(x) | intToLogicalBits(y))
}
35 %AND% 42 # 34 35 %OR% 42 # 42</lang> The bitops package has these operations done for you.
<lang R>library(bitops) bitAnd(35, 42) # 34 bitOr(35, 42) # 43 bitXor(35, 42) # 9 bitFlip(35, bitWidth=8) # 220 bitShiftL(35, 1) # 70 bitShiftR(35, 1) # 17
- Note that no bit rotation is provided in this package</lang>
Retro
There is no predefined arithmetic shifts in Retro.
<lang Retro>
- bitwise ( ab- )
cr over "a = %d\n" puts dup "b = %d\n" puts 2over and "a and b = %d\n" puts 2over or "a or b = %d\n" puts 2over xor "a xor b = %d\n" puts over not "not a = %d\n" puts 2over << "a << b = %d\n" puts 2over >> "a >> b = %d\n" puts 2drop ;</lang>
RLaB
In RLaB the bitwise operations are available for integers type of numbers. For the operations below if both arguments are integers then the result of the operation is an integer as well.
<lang RLaB>>> x = int(3); >> y = int(1); >> z = x && y; printf("0x%08x\n",z); // logical 'and' 0x00000001 >> z = x || y; printf("0x%08x\n",z); // logical 'or' 0x00000003 >> z = !x; printf("0x%08x\n",z); // logical 'not' 0xfffffffc >> i2 = int(2); >> z = x * i2; printf("0x%08x\n",z); // left-shift is multiplication by 2 where both arguments are integers 0x00000006 >> z = x / i2; printf("0x%08x\n",z); // right-shift is division by 2 where both arguments are integers 0x00000001</lang>
Ruby
<lang ruby>def bitwise(a, b)
puts "a and b: #{a & b}" puts "a or b: #{a | b}" puts "a xor b: #{a ^ b}" puts "not a: #{~a}" puts "a << b: #{a << b}" # left shift puts "a >> b: #{a >> b}" # arithmetic right shift
end</lang>
Scala
<lang scala>def bitwise(a: Int, b: Int) {
println("a and b: " + (a & b)) println("a or b: " + (a | b)) println("a xor b: " + (a ^ b)) println("not a: " + (~a)) println("a << b: " + (a << b)) // left shift println("a >> b: " + (a >> b)) // arithmetic right shift println("a >>> b: " + (a >>> b)) // unsigned right shift println("a rot b: " + Integer.rotateLeft(a, b)) // Rotate Left println("a rol b: " + Integer.rotateRight(a, b)) // Rotate Right
}</lang>
Scheme
<lang scheme>(define (bitwise a b)
(display (bitwise-and a b)) (newline) (display (bitwise-ior a b)) (newline) (display (bitwise-xor a b)) (newline) (display (bitwise-not a)) (newline) (display (bitwise-arithmetic-shift-right a b)) (newline))
(bitwise 255 5)</lang> Output: <lang>5 255 250 -256 7</lang>
Slate
<lang slate>[ |:a :b |
inform: (a bitAnd: b) printString. inform: (a bitOr: b) printString. inform: (a bitXor: b) printString. inform: (a bitNot) printString. inform: (a << b) printString. inform: (a >> b) printString.
] applyTo: {8. 12}.</lang>
Smalltalk
Since GNU Smalltalk by default runs without a graphical user interface, I wrote the program in that dialect. The actual methods for bitwise operations (bitAnd:, etc.) are the same in all implementations. <lang smalltalk>| testBitFunc | testBitFunc := [ :a :b |
('%1 and %2 is %3' % { a. b. (a bitAnd: b) }) displayNl. ('%1 or %2 is %3' % { a. b. (a bitOr: b) }) displayNl. ('%1 xor %2 is %3' % { a. b. (a bitXor: b) }) displayNl. ('not %1 is %2' % { a. (a bitInvert) }) displayNl. ('%1 left shift %2 is %3' % { a. b. (a bitShift: b) }) displayNl. ('%1 right shift %2 is %3' % { a. b. (a bitShift: (b negated)) }) displayNl. ].
testBitFunc value: 16r7F value: 4 .</lang>
Standard ML
For integers, IntInfs provide bitwise operations: <lang sml>fun bitwise_ints (a, b) = (
print ("a and b: " ^ IntInf.toString (IntInf.andb (IntInf.fromInt a, IntInf.fromInt b)) ^ "\n"); print ("a or b: " ^ IntInf.toString (IntInf.orb (IntInf.fromInt a, IntInf.fromInt b)) ^ "\n"); print ("a xor b: " ^ IntInf.toString (IntInf.xorb (IntInf.fromInt a, IntInf.fromInt b)) ^ "\n"); print ("not a: " ^ IntInf.toString (IntInf.notb (IntInf.fromInt a )) ^ "\n"); print ("a lsl b: " ^ IntInf.toString (IntInf.<< (IntInf.fromInt a, Word.fromInt b )) ^ "\n"); (* left shift *) print ("a asr b: " ^ IntInf.toString (IntInf.~>> (IntInf.fromInt a, Word.fromInt b )) ^ "\n") (* arithmetic right shift *)
)</lang> More shifts are available for words (unsigned ints): <lang sml>fun bitwise_words (a, b) = (
print ("a and b: " ^ Word.fmt StringCvt.DEC (Word.andb (a, b)) ^ "\n"); print ("a or b: " ^ Word.fmt StringCvt.DEC (Word.orb (a, b)) ^ "\n"); print ("a xor b: " ^ Word.fmt StringCvt.DEC (Word.xorb (a, b)) ^ "\n"); print ("not a: " ^ Word.fmt StringCvt.DEC (Word.notb a ) ^ "\n"); print ("a lsl b: " ^ Word.fmt StringCvt.DEC (Word.<< (a, b) ) ^ "\n"); (* left shift *) print ("a asr b: " ^ Word.fmt StringCvt.DEC (Word.~>> (a, b) ) ^ "\n"); (* arithmetic right shift *) print ("a asr b: " ^ Word.fmt StringCvt.DEC (Word.>> (a, b) ) ^ "\n") (* logical right shift *)
)</lang>
SystemVerilog
Verilog, being a hardware description language, had pretty comprehensive support for bit twiddling; though rotation is still a slightly manual operation. Just to be different, I decided to use a couple of 53-bit integers: <lang SystemVerilog>program main;
initial begin bit [52:0] a,b,c; a = 53'h123476547890fe; b = 53'h06453bdef23ca6;
c = a & b; $display("%h & %h = %h", a,b,c); c = a | b; $display("%h | %h = %h", a,b,c); c = a ^ b; $display("%h ^ %h = %h", a,b,c); c = ~ a; $display("~%h = %h", a, c);
c = a << 5; $display("%h << 5 = %h", a, c); c = a >> 5; $display("%h >> 5 = %h", a, c);
c = { a[53-23:0], a[52-:23] }; $display("%h rotate-left 23 = %h", a, c); c = { a[1:0], a[52:2] }; $display("%h rotate-right 2 = %h", a, c); end
endprogram</lang>
If we want to do a variable bit rotation, then we need to think in hardware terms, and build a mux structure (this could be a function, but using a module allows it to be parameterized:
<lang SystemVerilog>module rotate(in, out, shift);
parameter BITS = 32; parameter SHIFT_BITS = 5;
input [BITS-1:0] in; output [BITS-1:0] out; input [SHIFT_BITS-1:0] shift;
always_comb foreach (out[i]) out[i] = in[ (i+shift) % BITS ];
endmodule</lang>
of course, one could always write the foreach loop inline.
Tcl
<lang tcl>proc bitwise {a b} {
puts [format "a and b: %#08x" [expr {$a & $b}]] puts [format "a or b: %#08x" [expr {$a | $b}]] puts [format "a xor b: %#08x" [expr {$a ^ $b}]] puts [format "not a: %#08x" [expr {~$a}]] puts [format "a << b: %#08x" [expr {$a << $b}]] puts [format "a >> b: %#08x" [expr {$a >> $b}]]
}</lang> There are no built-in operations for arithmetic right shift or for bit rotation. Indeed, rotation precludes the use of arbitrary-width integers and can only be defined with respect to a particular width. However, we can simulate these operations for 32-bit values (requires Tcl 8.5): <lang tcl>proc bitwiseUnsupported {a b} {
set bits 0xFFFFFFFF # Force interpretation as a 32-bit unsigned value puts [format "a ArithRightShift b: %#08x" [expr {($a & $bits) >> $b}]] puts [format "a RotateRight b: %#08x" [expr { (($a >> $b) & ($bits >> $b)) | (($a << (32-$b)) & ($bits ^ ($bits >> $b))) }]] puts [format "a RotateLeft b: %#08x" [expr { (($a << $b) & $bits & ($bits << $b)) | (($a >> (32-$b)) & ($bits ^ ($bits << $b))) }]]
}</lang>
TI-89 BASIC
While the TI-89 supports arbitrary-size integers, all bitwise arithmetic is performed on the rightmost 32 bits of the integers' two's complement representation.
The right shift operation fills the new leftmost bit with a copy of the old leftmost bit.
<lang ti89b>bitwise(a,b) Prgm
Local show, oldbase Define show(label, x)=Prgm Local r setMode("Base","DEC") string(x) → r setMode("Base","HEX") Disp label & r & " " & string(x) EndPrgm getMode("Base") → oldbase show("", {a, b}) show("And ", a and b) show("Or ", a or b) show("Xor ", a xor b) show("Not ", not a) Pause "[Press ENTER]" show("LSh ", shift(a,b)) show("RSh ", shift(a,–b)) show("LRo ", rotate(a,b)) show("RRo ", rotate(a,–b)) setMode("Base",oldbase)
EndPrgm</lang>
Visual Basic .NET
<lang vbnet>Sub Test(a as Integer, b as Integer)
WriteLine("And " & a And b) WriteLine("Or " & a Or b) WriteLine("Xor " & a Xor b) WriteLine("Not " & Not a) WriteLine("Left Shift " & a << 2) WriteLine("Right Shift " & a >> 2)
End Sub</lang>
Visual Basic doesn't have built-in support for bitwise rotation.
x86 Assembly
It must be linked with the libc and "start" code; lazyly a gcc bitops.o works, being bitops.o produced by nasm -f elf bitops.asm (I've chosen ELF since I am on a GNU/Linux box) <lang asm> extern printf global main
section .text main mov eax, dword [_a] mov ecx, dword [_b] push ecx push eax
and eax, ecx mov ebx, _opand call out_ops
call get_nums or eax, ecx mov ebx, _opor call out_ops
call get_nums xor eax, ecx mov ebx, _opxor call out_ops
call get_nums shr eax, cl mov ebx, _opshr call out_ops
call get_nums shl eax, cl mov ebx, _opshl call out_ops
call get_nums rol eax, cl mov ebx, _oprol call out_ops
call get_nums ror eax, cl mov ebx, _opror call out_ops
call get_nums sal eax, cl mov ebx, _opsal call out_ops
call get_nums sar eax, cl mov ebx, _opsar call out_ops
mov eax, dword [esp+0] not eax push eax not eax push eax push _opnot push _null push _testn call printf add esp, 20
add esp, 8 ret
out_ops push eax push ecx push ebx push dword [_a] push _test call printf add esp, 20 ret
get_nums mov eax, dword [esp+4] mov ecx, dword [esp+8] ret
section .data
_a dd 11 _b dd 3
section .rodata _test db '%08x %s %08x = %08x', 10, 0 _testn db '%08s %s %08x = %08x', 10, 0 _opand db 'and', 0 _opor db 'or ', 0 _opxor db 'xor', 0 _opshl db 'shl', 0 _opshr db 'shr', 0 _opror db 'ror', 0 _oprol db 'rol', 0 _opnot db 'not', 0 _opsal db 'sal', 0 _opsar db 'sar', 0 _null db 0
end</lang>
- Programming Tasks
- Discrete math
- Basic Data Operations
- ActionScript
- Ada
- Aikido
- ALGOL 68
- AutoHotkey
- AWK
- BASIC
- BBC BASIC
- C
- C++
- C sharp
- Clojure
- Common Lisp
- D
- Delphi
- E
- F Sharp
- Factor
- FALSE
- Forth
- Fortran
- Go
- Groovy
- Haskell
- HicEst
- Icon
- Unicon
- J
- Java
- JavaScript
- Liberty BASIC
- LLVM
- Logo
- Lua
- LSE64
- LSE64 examples needing attention
- Examples needing attention
- Mathematica
- MATLAB
- MAXScript
- Modula-3
- Nemerle
- NSIS
- Objeck
- OCaml
- Octave
- PARI/GP
- Pascal
- Perl
- Perl 6
- PHP
- PicoLisp
- PL/I
- Pop11
- PureBasic
- Python
- R
- Bitops
- Retro
- RLaB
- Ruby
- Scala
- Scheme
- Slate
- Smalltalk
- Standard ML
- SystemVerilog
- Tcl
- TI-89 BASIC
- Visual Basic .NET
- X86 Assembly