The bitwise operations related to a fast sorting algorithm

In the work we discuss the benefit of using bitwise operations in programming. Some interesting examples in this respect have been shown. What is described in detail is an algorithm for sorting an integer array with the substantial use of the bitwise operations. Besides its correctness we strictly prove that the described algorithm works in time O(n). In the work during the realisation of each of the examined algorithms we use the apparatus of the object-oriented programming with the syntax and the semantics of the programming language C++.


I. INTRODUCTION
The use of bitwise operations is a powerful means during programming with the languages C/C++ and Java. Some of the strong sides of these programming languages are the possibilities of low level programming. Some of the means for this possibility are the introduced standard bitwise operations, with the help of which it is possible to directly operate with every bit of an arbitrary variable situated in the random access memory of the computer. In the current article we are going to describe some methodical aspects for work with the bitwise operations.
As an interesting example of application of the bitwise operations comes the realised by us algorithm for sorting an integer array, for which we strictly prove its correctness and the fact that this algorithm will use O(n) operations included in the standard of the programming language C++. A main role in the realisation of the algorithm play the bitwise operations.
II. BITWISE OPERATIONS The bitwise operations can be applied for integer data type only. For the definition of the bitwise operations and some of their elementary applications could be seen, for example, in [2], [5] for C/C++ programming languages and in [4], [7] for Java programming language.
We assume, as usual that bits numbering in variables starts from right to left, and that the number of the very right one is 0.
Let x and y be integer variables or constants and let z be integer variables of one type, for which w bits are needed. Let x and y be initialized (if they are variables) and let the assignment z = x & y; (bitwise AND), or z = x | y; (bitwise inclusive OR), or z = xˆy; (bitwise exclusive OR), or z =˜x; (bitwise NOT) be made. For each i = 0, 1, 2, . . . , w − 1, the new contents of the i-th bit in z will be as it is presented in the Table I. In case that k is a nonnegative integer, then the statement z = x<<k; (bitwise shift left) will write in the (i + k) bit of z the value of the k bit of x, where i = 0, 1, . . . , w − k − 1, and the very right k bits of x will be filled by zeroes. This operation is equivalent to a multiplication of x by 2 k .
The statement z=x>>k (bitwise shift right) works the similar way. But we must be careful if we use the programming language C or C++, as in various programming environments this operation has different interpretations -somewhere k bits of z from the very left place are compulsory filled by 0 (logical displacement), and elsewhere the very left k bits of z are filled with the value from the very left (sign) bit; i.e. if the number is negative, then the filling will be with 1 (arithmetic displacement). Therefore it is recommended to use unsigned type of variables (if the opposite is not necessary) while working with bitwise operations (see also Example 3). In the Java programming language, this problem is solved by introducing the two different operators: z=x>>k and z=x>>>k [4], [7].
Bitwise operations are left associative. The priority of operations in descending order is as follows: (bitwise NOT); the arithmetic operations * (multiply), / (divide), % (remainder or modulus); the arithmetic operations + When we work with negative numbers we must consider that in the computer the presentation of the negative numbers is through the so called true complement code. The following function gives us how to code the integers in the memory of the computer we work with. For simplicity we are going to work with type short, but it is not a problem for the function to be overloaded for other integer types, too. Some experiments with the function BinRepl are given in Table II.
Compare the function presented in Example 4 to the next function presented in Example 5.
Example 5: A function that prints a given integer in binary notation.
The following function calculates the number of 1 in a given integer n written in a binary notation. Here again we ignore the sign of the number (if it is negative) and we work with its absolute value. int NumbOf_1(int n) { n = abs(n); int temp=0; int d = sizeof(int) * 8 -1; for (int i=0; i<d; i++) if (n & 1<<i) temp++; return temp; }

IV. BITWISE SORTING
In this section we are going to suggest a fast algorithm for sorting an arbitrary integer array. And since during its realisation we are substantially going to use bitwise operations, we will call it "Bitwise sorting". We will prove that the bitwise sorting works in time O(n), where n is the size of the array. This is an excellent evaluation regarding the criterion time. For comparison below we give some of the most famous sorting algorithms and their evaluations by criterion time [1], [6], [8]. where m is another parameter, giving the number of the unique keys, and it is also necessary to have knowledge of the nature of the sorted data which goes beyond the functions "swap" and "compare".

V. PROGRAMME CODE OF THE ALGORITHM
The algorithm created by us, described with the help of programming language C++, is shown below (algorithm 1). Due to some obvious reasons, first we create a function which sorts an array whose elements are either only nonnegative, or only negative. The second function divides the given array into two disjoint subarrays respectively only with negative and only with nonnegative elements. After sorting each one of these subarrays, we merge them so that we obtain one finally sorted array.
Algorithm 1: Bitwise sorting.  As a main disadvantage of the algorithm described by us comes the fact that it is applicable only to arrays of integers or symbols (type char). This is because for it we substantially use bitwise operations, which are applicable only over integer types of data. But this disadvantage is compensated by its high speed. As we will see below, algorithm 1 works in time O(n), where n is the number of the elements which are subjected to sorting.
Except through the multiple experiments which we have made, with the help of the following theorem we will prove the correctness of the algorithm created by us.
Theorem 1: During every execution of algorithm 1 with an arbitrary input array of integers, as a result a sorted array is obtained.
Proof. It is enough to prove that function BitwiseSort1 works so as to fulfill the conditions of the theorem.
Let A = {a 0 , a 1 , . . . , a n−1 } be an arbitrary integer array with length n and let n−1 } be the array which is obtained after iteration with number k, where k = 0, 1, . . . , t − 2, t=sizeof(T)*8, i.e. t is equal to the number of the bits which every element of A occupies in the memory of the computer.
Let x be an integer. For every natural number k = 0, 1, 2, . . . we define the functions: where just like in programming languages C/C++ and Java the operator % denotes the remainder during integer division. Apparently µ s−1 (x) = x if the absolute value of the integer x can be written with no more than s digits 0 or 1 in a binary notation. Therefore in order to prove that as a result of the work of the algorithm the array A (t−2) is sorted, it is enough to prove that the array n−1 )} is sorted. Applying inductive reasoning, we will prove that for every s, such that 0 ≤ s < t − 1, the array A (s) = {µ s (a When s = 0 the assertion follows from the fact that during iteration with number 0 (k = 0), A (0) is ordered so that first come all elements of the array which in their binary notation end in 0, followed by all elements of the array which in their binary notation end in 1.
We assume that for a certain natural number s, 0 ≤ s < t−2 the array A (s) = {µ s (a n−1 )} is sorted. But then analysing the work of the algorithm in (s+1)-th iteration, it is easy to see that the array A0, which is obtained from A (s) taking in the same row only these elements of A (s) having 0 in bit with number s + 1 , is a sorted array. Analogously we prove that the array A1 is sorted and in bit with number s + 1 on each of its elements stands 1. Then the array n−1 )}, which is obtained from the merger of the arrays A0 and A1 where the elements of A0 precede the elements of A1, is sorted. And with this we have proven the theorem.
Theorem 2: Algorithm 1 described with the help of programming language C++ works in time O(n).
Proof. The assertion of the theorem follows from the fact that in function BitwiseSort1 we have only two nested loops. In the inner loop exactly n iterations are performed, and in every iteration once the operation & (bitwise conjunction), once the operation << (bitwise shift left), once the if statement, once the assignment statement and once the increment statement are performed. Each of the aforesaid operations is performed in constant time. The outer loop does t − 2 iterations, where t is a constant, and in every iteration besides the inner loops there are also two assignment operations.
In function BitwiseSort the division of the array into two disjoing subarrays is performed apparently in time O(n). The newly obtained two arrays are sorted in total time O(n). The following merger of the two sorted arrays with total length n is apparently also performed in time O(n).