Bit shifts: Difference between revisions

From Rosetta Code
Content added Content deleted
(php)
(Ada)
Line 8:
 
If possible, perform the right shifts on a negative number, so one can distinguish between the arithmetic and logical shifts.
 
=={{header|Ada}}==
Ada shifting operations only work on unsigned numbers. The right shift arithmetic shifts one bits if the value being shifted is at least half the modulus of the unsigned type. The example below uses an 8-bit unsigned type and a value of 128 to demonstrate this behavior. Ada also provide functions to rotate left and rotate right, which are not part of this task.
<ada>
with Interfaces; use Interfaces;
with Ada.Text_Io; use Ada.Text_Io;
 
procedure Bit_Shifts is
X : Unsigned_8 := 128;
N : Natural := 1;
begin
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
end Bit_Shifts;
</ada>
Output of the above program:
0
64
192
 
 
=={{header|C}}==

Revision as of 18:56, 18 May 2008

Task
Bit shifts
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


Perform the following bit shifts, if supported in your language:

  • Logical / arithmetic left shift - left shift where vacated bits are filled with 0; usually equivalent to multiplying integer by 2^N
  • Arithmetic right shift - right shift where vacated bits are filled with the sign bit; usually equivalent to dividing signed integer by 2^N, rounding downwards towards negative infinity
  • Logical right shift - right shift where vacated bits are filled with 0; usually equivalent to dividing unsigned integer by 2^N

If possible, perform the right shifts on a negative number, so one can distinguish between the arithmetic and logical shifts.

Ada

Ada shifting operations only work on unsigned numbers. The right shift arithmetic shifts one bits if the value being shifted is at least half the modulus of the unsigned type. The example below uses an 8-bit unsigned type and a value of 128 to demonstrate this behavior. Ada also provide functions to rotate left and rotate right, which are not part of this task. <ada> with Interfaces; use Interfaces; with Ada.Text_Io; use Ada.Text_Io;

procedure Bit_Shifts is

  X : Unsigned_8 := 128;
  N : Natural := 1;

begin

  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

end Bit_Shifts; </ada> Output of the above program:

0
64
192


C

The C standard does not specifies what happens if you try to shift a negative signed integer. The behavior is therefore implementation-dependent. Typically, it performs an arithmetic shift in this case.

<c>#include <stdio.h> int main() {

 int x = -3;
 int n = 1;
 /* convert the signed integer into unsigned, so it will perform logical shift */
 unsigned int y = x;
 printf("x << n: %d\n", x << n); /* left shift */
 printf("x >> n: %d\n", x >> n); /* arithmetic right shift */
 printf("y >> n: %d\n", y >> n); /* logical right shift */
 return 0;

}</c>

The output of this program on a typical platform is:

x << n: -6
x >> n: -2
y >> n: 2147483646

Haskell

The first operand can be Int, Integer, and any of the sized integer and word types. The second operand must be of type Int.

import Data.Bits

x :: Integer
x = -3
n :: Int
n = 1

main = do
  print $ shiftL x n -- left shift
  print $ shiftR x n -- arithmetic right shift
  print $ shift x n  -- You can also use the "unified" shift function; positive is for left shift, negative is for right shift
  print $ shift x (-n)

The output of this program on a typical platform is:

-6
-2
-6
-2

Java

<java>public static void main(String[] args) {

   int x = -3;
   int n = 1;
   System.out.println("x << n: " + (x << n)); // left shift
   System.out.println("x >> n: " + (x >> n)); // arithmetic right shift
   System.out.println("x >>> n: " + (x >>> n)); // logical right shift

}</java>

The output of this program is:

x << n: -6
x >> n: -2
x >>> n: 2147483646

JavaScript

<javascript>var x = -3; var n = 1; alert("x << n: " + (x << n)); // left shift alert("x >> n: " + (x >> n)); // arithmetic right shift alert("x >>> n: " + (x >>> n)); // logical right shift</javascript>

The output of this program is:

x << n: -6
x >> n: -2
x >>> n: 2147483646

OCaml

<ocaml>let x = -3;; let n = 1;;

Printf.printf "x lsl n: %d\n" (x lsl n);; (* left shift *) Printf.printf "x asr n: %d\n" (x asr n);; (* arithmetic right shift *) Printf.printf "x lsr n: %d\n" (x lsr n);; (* logical right shift *)</ocaml>

The output of this program is:

x lsl n: -6
x asr n: -2
x lsr n: 1073741822

Note that "int" in OCaml is 31 bits wide.

Perl

<perl>$x = -3; $n = 1; print '$x >> $n: ', $x >> $n, "\n"; # logical right shift

use integer; # "use integer" enables bitwise operations to return signed ints print "after use integer:\n"; print '$x << $n: ', $x << $n, "\n"; # left shift print '$x >> $n: ', $x >> $n, "\n"; # arithmetic right shift</perl>

Output:

$x >> $n: 2147483646
after use integer:
$x << $n: -6
$x >> $n: -2

PHP

<php>$x = -3; $n = 1; echo '$x << $n: ', $x << $n, "\n"; // left shift echo '$x >> $n: ', $x >> $n, "\n"; // arithmetic right shift</php>

The output of this program is:

$x << $n: -6
$x >> $n: -2

Python

<python>x = -3 n = 1 print 'x << n:', x << n # left shift print 'x >> n:', x >> n # arithmetic right shift</python>

The output of this program is:

x << n: -6
x >> n: -2