Bitwise operations: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 42: Line 42:
* 2r00000000000000000000000010101010, 4r0000000000002222, 8r00000000252, 16r000000aa
* 2r00000000000000000000000010101010, 4r0000000000002222, 8r00000000252, 16r000000aa
* and as an array of BOOL: FFFFFFFFFFFFFFFFFFFFFFFFTFTFTFTF
* and as an array of BOOL: FFFFFFFFFFFFFFFFFFFFFFFFTFTFTFTF
<lang=algol>main:(
<pre>main:(


PRIO SLC = 8, SRC = 8; # SLC and SRC are not built in, define and overload them here #
PRIO SLC = 8, SRC = 8; # SLC and SRC are not built in, define and overload them here #
Line 105: Line 105:
bitwise(16rff,16raa,5)
bitwise(16rff,16raa,5)
END CO
END CO
)</lang>
)</pre>
Output:<pre>
Output:<pre>
bits shorths: +1 1 plus the number of extra SHORT BITS types
bits shorths: +1 1 plus the number of extra SHORT BITS types

Revision as of 03:50, 5 September 2009

Task
Bitwise operations
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 function 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.

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>

ALGOL 68

Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386

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
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
)

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

Works with: gawk

Standard awk does not have bitwise operators. No rotation of bits, nor bitwise not (which can be simulated through a xor)

<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)
 print n " >>  " p " = " rshift(n, p)
 printf "simulated not %d = 0x%08x\n", n, xor(n, 0xffffffff) 

}</lang>

BASIC

Works with: QuickBasic version 4.5

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>

Works with: FreeBASIC

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>

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>

C++

Translation of: C

<lang cpp>

  1. 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>

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)

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>

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

outputs:

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

Currently rotation and logical shifts are not implemented.

FALSE

Only AND, OR, and NOT are available.

10 3
\$@$@$@$@\  { 3 copies }
"a & b = "&."
a | b  = "|."
~a = "%~."
"

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 ;

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>

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

J

Actual calculations occur in bwo and brs. Other definitions provide formatting.

bwo     =: 17 b. , 23 b. , 22 b. , 28 b.
brs     =: 33 b.~ , (33 b.~ -), (34 b.~ -), 32 b.~ , (32  b.~ -)
boolf   =: title"_ combine bwo, brs
combine =: ,. ":@|:@,:
t    =. >;._2 'Bitwise x AND y: |Bitwise x OR y:|Bitwise x XOR y:|Bitwise NOT-x:|'
title=: t,>;._2'Left shift:|Right shift:|Right signed shift:|Left rotate:|Right rotate:|'
f=: (32#2)&#: { '.x'"_

Examples of execution, with output:

   _255 bwo 5        NB. numeric output of bitwise operations
1 _251 _252 254
   _255 brs 5        NB. numeric output of boolean rotation and shift operations
_8160 134217720 _8 _8129 268435448
   _255 boolf 5      NB. formatted text with English titling
Bitwise x AND y:           1
Bitwise x OR y:         _251
Bitwise x XOR y:        _252
Bitwise NOT-x:           254
Left shift:            _8160
Right shift:       134217720
Right signed shift:       _8
Left rotate:           _8129
Right rotate:      268435448
   f _255 (bwo, brs) 5   NB. 32-bit diagrams
...............................x
xxxxxxxxxxxxxxxxxxxxxxxx.....x.x
xxxxxxxxxxxxxxxxxxxxxxxx.....x..
........................xxxxxxx.
xxxxxxxxxxxxxxxxxxx.......x.....
.....xxxxxxxxxxxxxxxxxxxxxxxx...
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
xxxxxxxxxxxxxxxxxxx.......xxxxxx
....xxxxxxxxxxxxxxxxxxxxxxxxx...

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>

Works with: UCB 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

The output of this program is:

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

LSE64

This example is incorrect. It does not accomplish the given task. Please fix the code and remove this message.
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

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>

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

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(a, b)) & "\n");
   IO.Put("c RightShift b: " & Fmt.Unsigned(Word.RightShift(a, b)) & "\n");
   IO.Put("c LeftRotate b: " & Fmt.Unsigned(Word.LeftRotate(a, b)) & "\n");
   IO.Put("c RightRotate b: " & Fmt.Unsigned(Word.RightRotate(a, 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

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>

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>

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>

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;

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.

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.

Library: bitops

<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

  1. Note that no bit rotation is provided in this package

</lang>

Ruby

<lang ruby>def 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" # left shift
       print 'a >> b: ', a >> b, "\n" # arithmetic right shift

end</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

Works with: GNU 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>

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.

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

Visual Basic .NET

<lang vb>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

Works with: nasm

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>