Bitwise operations: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|C}}: small correction)
Line 61: Line 61:
printf("not a: %d\n", ~a);
printf("not a: %d\n", ~a);
printf("a << n: %d\n", a << b); /* left shift */
printf("a << n: %d\n", a << b); /* left shift */
printf("a >> n: %d\n", a >> b); /* arithmetic right 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 */
/* convert the signed integer into unsigned, so it will perform logical shift */
unsigned int c = a;
unsigned int c = a;
printf("c >> b: %d\n", c >> b); /* logical right shift */
printf("c >> b: %d\n", c >> b); /* logical right shift */
}</c>
}</c>

=={{header|D}}==
=={{header|D}}==
{{incorrect|D}}
{{incorrect|D}}

Revision as of 20:35, 20 May 2008

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.

<ada> with Ada.Text_Io; use Ada.Text_Io;

procedure Bitwise is
   type Byte is mod 2**8;
   package Byte_Io is new Ada.Text_Io.Modular_Io(Byte);
   
   A : Byte := 255;
    B : Byte := 170;
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);
  Put_Line(Unsigned_8'Image(Shift_Left(A, B))); -- Left shift
  Put_Line(Unsigned_8'Image(Shift_Right(A, B))); -- Right shift
  Put_Line(Unsigned_8'Image(Shift_Right_Arithmetic(A, B))); -- Right Shift Arithmetic
  Put_Line(Unsigned_8'Image(Rotate_Left(A, B))); -- Left rotate
  Put_Line(Unsigned_8'Image(Rotate_Right(A, B))); -- Right rotate
end bitwise;</ada>

ALGOL 68

This example is incorrect. It does not accomplish the given task. Please fix the code and remove this message.
PROC bitwise = (BITS a, BITS b)VOID:
(
  printf(($"a and b: "gl$, a AND b));
  printf(($"a or b: "gl$, a OR b));
  printf(($"a xor b: "gl$, a XOR b));
  printf(($"not a: "gl$, NOT a))
);
bitwise(BIN 255, BIN 170)

The output of this program is:

a and b: FFFFFFFFFFFFFFFFFFFFFFFFTFTFTFTF
a or b: FFFFFFFFFFFFFFFFFFFFFFFFTTTTTTTT
a xor b: FFFFFFFFFFFFFFFFFFFFFFFFFTFTFTFT
not a: TTTTTTTTTTTTTTTTTTTTTTTTFFFFFFFF

BASIC

Works with: QuickBasic version 4.5

QuickBasic does not have shift or rotate operations defined. Here are the logical operations:

SUB bitwise (a, b)
  PRINT a AND b
  PRINT a OR b
  PRINT a XOR b
  PRINT NOT a
END SUB

C

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

}</c>

D

This example is incorrect. It does not accomplish the given task. Please fix the code and remove this message.
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("NOT  : %8s ~ %08b = %032b (%4d)", "", a, ~a, ~a) ;
}

void main() {
  int a = 0b11111111 ; // bit literal 255
  int b = 0b10101010 ; // bit literal 170
  
  testbit(a,b) ;  
}

Output:

Input:  a = 255 , b = 170
AND  : 11111111 & 10101010 = 00000000000000000000000010101010 ( 170)
 OR  : 11111111 | 10101010 = 00000000000000000000000011111111 ( 255)
XOR  : 11111111 ^ 10101010 = 00000000000000000000000001010101 (  85)
NOT  :          ~ 11111111 = 11111111111111111111111100000000 (-256)

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:

   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)

Haskell

The operations in Data.Bits work on Int, Integer, and any of the sized integer and word types.

import Data.Bits

a = 255
b = 170

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)

J

This example is incorrect. It does not accomplish the given task. Please fix the code and remove this message.

Actual bitwise calculation occurs in bwo. Other definitions provide formatting.

bwo     =: 17 b. , 23 b. , 22 b. , 28. b.
bwotxt  =: title"_ combine bwo
combine =: [ ,. ":@|:@,:@]
title   =: >;._2 'Bitwise x AND y: |Bitwise x OR y:|Bitwise x XOR y:|Bitwise NOT-x:|'
f       =: (32#2)&#: { '.x'"_

Examples of execution, with output:

   255 bwo 170        NB. numeric output
170 255 85 _256
   255 bwotxt 170     NB. formatted text with English titling
Bitwise x AND y:  170
Bitwise x OR y:   255
Bitwise x XOR y:   85
Bitwise NOT-x:   _256
   f 255 bwo 170      NB. 32-bit diagram
........................x.x.x.x.
........................xxxxxxxx
.........................x.x.x.x
xxxxxxxxxxxxxxxxxxxxxxxx........

Java

<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

}</java>

JavaScript

<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

}</javascript>

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

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.

OCaml

<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 *)</ocaml>

Perl

<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

}</perl>

PHP

This example is incorrect. It does not accomplish the given task. Please fix the code and remove this message.

<php>echo '$a << $b: ', $a << $b, "\n"; // left shift echo '$a >> $b: ', $a >> $b, "\n"; // arithmetic right shift</php>

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

<python>def bitwise(a, b):

       print 'a and b: ' + str(a & b)
       print 'a or b: '  + str(a | b)
       print 'a xor b: ' + str(a ^ b)
       print 'not a: '   + str(~a)
       print 'a << b:', a << b # left shift
       print 'a >> b:', a >> b # arithmetic right shift</python>

Smalltalk

This example is incorrect. It does not accomplish the given task. Please fix the code and remove this message.

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.

a := stdin nextLine asInteger.
b := stdin nextLine asInteger.
('a and b: %1' % {a bitAnd: b}) displayNl.
('a or b: %1' % {a bitOr: b}) displayNl.
('a xor b: %1' % {a bitXor: b}) displayNl.
('not a: %1' % {a bitInvert}) displayNl.