Generalizing binary left shift for octal representation without conversion - c++

Currently I have a few lines of code for working with binary strings in their decimal representation, namely I have functions to rotate the binary string to the left, flip a specific bit, flip all bits and reverse order of the binary string all working on the decimal representation. They are defined as follows:
inline u64 rotate_left(u64 n, u64 maxPower) {
return (n >= maxPower) ? (((int64_t)n - (int64_t)maxPower) * 2 + 1) : n * 2;
}
inline bool checkBit(u64 n, int k) {
return n & (1ULL << k);
}
inline u64 flip(u64 n, u64 maxBinaryNum) {
return maxBinaryNum - n - 1;
}
inline u64 flip(u64 n, u64 kthPower, int k) {
return checkBit(n, k) ? (int64_t(n) - (int64_t)kthPower) : (n + kthPower);
}
inline u64 reverseBits(u64 n, int L) {
u64 rev = (lookup[n & 0xffULL] << 56) | // consider the first 8 bits
(lookup[(n >> 8) & 0xffULL] << 48) | // consider the next 8 bits
(lookup[(n >> 16) & 0xffULL] << 40) | // consider the next 8 bits
(lookup[(n >> 24) & 0xffULL] << 32) | // consider the next 8 bits
(lookup[(n >> 32) & 0xffULL] << 24) | // consider the next 8 bits
(lookup[(n >> 40) & 0xffULL] << 16) | // consider the next 8 bits
(lookup[(n >> 48) & 0xffULL] << 8) | // consider the next 8 bits
(lookup[(n >> 54) & 0xffULL]); // consider last 8 bits
return (rev >> (64 - L)); // get back to the original maximal number
}
WIth the lookup[] list defined as:
#define R2(n) n, n + 2*64, n + 1*64, n + 3*64
#define R4(n) R2(n), R2(n + 2*16), R2(n + 1*16), R2(n + 3*16)
#define R6(n) R4(n), R4(n + 2*4 ), R4(n + 1*4 ), R4(n + 3*4 )
#define REVERSE_BITS R6(0), R6(2), R6(1), R6(3)
const u64 lookup[256] = { REVERSE_BITS };
All but the last one are easy to implement.
My question is whether you know any generalization of the above functions for the octal string of a number, while working only on the decimal representation as above? Obviously without doing a conversion and storing the octal string itself (mainly due to performance boost)
With flip() in octal code a would need to return the number with 8-x at the specified place in the string (for intstance: flip(2576, 2nd power, 2nd position) = 2376, i.e. 3 = 8-5).
I do understand that in octal representation the any similar formulas as for rotate_left or flip are not possible (maybe?), that is why I look for alternative implementation.
A possibility would be to represent each number in the octal string by their binary string, in other words to write: 29 --octal-> 35 --bin-> (011)(101)
Thus working on sets of binary numbers. Would that be a good idea?
If you have any suggestions for the code above for binary representation, I welcome any piece of advice.
Thanks in advance and sorry for the long post!

my understand of rotate_left, do not know my understand of question is correct, hope this will help you.
// maxPower: 8
// n < maxPower:
// 0001 -> 0010
//
// n >= maxPower
// n: 1011
// n - maxPower: 0011
// (n - maxPower) * 2: 0110
// (n - maxPower) * 2 + 1: 0111
inline u64 rotate_left(u64 n, u64 maxPower) {
return (n >= maxPower) ? (((int64_t)n - (int64_t)maxPower) * 2 + 1) : n * 2;
}
// so rotate_left for octadecimal, example: 3 digit octadecimal rotate left.
// 0 1 1 -> 1 1 0
// 000 001 001 -> 001 001 000
// 4 4 0 -> 4 0 4
// 100 100 000 -> 100 000 100
// so, keep:
// first digit of octadecimal number is:
// fisrt_digit = n & (7 << ((digit-1) * 3))
// other digit of octadecimal number is:
// other_digit = n - first_digit
// example for 100 100 000:
// first_digit is 100 000 000
// other_digit is 000 100 000
// so rotate left result is:
// (other_digit << 3) | (first_digit >> ((digit-1) * 3))
//
inline u64 rotate_left_oct(u64 n, u64 digit) {
u64 rotate = 3 * (digit - 1);
u64 first_digit = n & (7 << rotate);
u64 other_digit = n - first_digit;
return (other_digit << 3) | (first_digit >> rotate);
}
flip, for base 8, flip should be 7-x instead of 8-x:
// oct flip same with binary flip:
// (111)8 -> (001 001 001)2
// flip,
// (666)8 -> (110 110 110)2
// this should be 7 - 1, not 8 - 1, indead.
//
inline u64 flip_oct(u64 n, u64 digit) {
u64 maxNumber = (1 << (3 * digit)) - 1;
assert(n <= maxNumber);
return maxNumber - n;
}
// otc flip one digit
// (111)8 -> (001 001 001)2
// flip 2nd number of it
// (161)8 -> (001 110 001)2
// just need do xor of nth number of octadecimal number.
//
inline u64 flip_oct(u64 n, u64 nth, u64 digit) {
return (7 << (3 * (nth - 1))) ^ n;
}
simple reverse.
inline u64 reverse_oct(u64 n, u64 digit) {
u64 m = 0;
while (digit > 0) {
m = (m << 3) | (n & 7);
n = n >> 3;
--digit;
}
return m;
}

Related

Branch free saturation

I have the following calculation:
unsigned int a;
unsigned b = (a < 4) ? a : 4;
Is it possible to convert the second line to a branch free format?
Thanks!
Try this:
b = (a >= 4) * 4 + (a < 4) * ((a >> 1) & 1) * 2 + (a < 4) * (a & 1);
Explanation: we are returning 4 by "zeroing" the 2 least significant bits if a >= 4. If a < 4, we use these 2 least significant bits.
You could use a conditionally applied mask:
unsigned int a, b, t, m;
t = a - 4;
m = 0 - ((int)t < 0); // mask of all 0s or all 1s
b = (t & m) + 4; // mask all 1s: b=a-4+4; mask all 0s: b=4

Integer subtraction with wrap around for N bits

Basically, the behavior you get when overflowing integers with subtraction, but for a given number of bits. The obvious way, assuming a signed integer:
template <int BITS>
int sub_wrap(int v, int s) {
int max = (1<<(BITS));
v -= s;
if (v < -max) v += max*2;
// or if branching is bad, something like:
// v += (max*2) * (v < -max)
return v;
}
// For example subtracting 24 from -16 with 5 bit wrap,
// with a range of -32, 31
sub_wrap<5>(-16, 28); -> 20
Is there a neat way of doing it that is less ugly and preferably faster than the one above?
UPDATE: Sorry about the confusion. I thoughtlessly included the confusing notation of using the number of bits excluding the sigh bit. So in the above, replace 5 bits with 6 bits for a lot more sanity.
For unsigned arithmetic, and mask the results, e.g.:
template<int bits>
unsigned
sub_wrap( unsigned v, unsigned s )
{
return (v - s) & ((1 << bits) - 1);
}
More generally, you can use the modulo operator:
template<int modulo>
unsigned
sub_wrap( unsigned v, unsigned s )
{
return (v - s) % modulo;
}
(Wrapping on n bits is the equivalent of modulo 2^n.)
For signed arithmetic, it's a bit more complex; using the mask, you'll have to sign extend the results (supposing 2's complement).
EDIT: Using sehe's suggestion for signed arithmetic:
template<int bits>
int
sub_wrap( int v, int s )
{
struct Bits { signed int r: bits; } tmp;
tmp.r = v - s;
return tmp.r;
}
Given this, sub_wrap<5>( -16, 28 ) gives -12 (which is correct—note that 28 cannot be represented as signed int in 5 bits); sub_wrap<6>( -16, 28 ) gives 20.
I suppose this should work:
struct bits
{
signed int field : 5;
};
bits a = { -16 };
bits b = { 28 };
bits c = { a.field - b.field };
std::cout << c.field << std::endl;
I'm pretty sure the field width won't work with a const template argument... and hence this is less generic. It should, however, avoid manual tinkering. Will post test soon
Update It turns out my answer wasn't incorrect after all. It is just that the sample input (28) cannot be represented in 5 bits (signed). The outcome of the above is -12 (see http://ideone.com/AUrXy).
Here is, for completeness, a templated version after all:
template<int bits>
int sub_wrap(int v, int s)
{
struct helper { signed int f: bits; } tmp = { v };
return (tmp.f -= s);
}
Here's how I'd do it w/o conditional branches and multiplication:
#include <stdio.h>
// Assumptions:
// - ints are 32-bit
// - signed ints are 2's complement
// - right shifts of signed ints are sign-preserving arithmetic shifts
// - signed overflows are harmless even though strictly speaking they
// result in undefined behavior
//
// Requirements:
// - 0 < bits <= 32
int sub_wrap(int v, int s, unsigned bits)
{
int d = v - s;
unsigned m = ~0u >> (32 - bits);
int r = d & m | -((d >> (bits - 1)) & 1) & ~m;
return r;
}
#define BITS 2
int main(void)
{
int i, j;
for (i = -(1 << (BITS - 1)); i <= (1 << (BITS - 1)) - 1; i++)
for (j = -(1 << (BITS - 1)); j <= (1 << (BITS - 1)) - 1; j++)
printf("%d - %d = %d\n", i, j, sub_wrap(i, j, BITS));
return 0;
}
Output:
-2 - -2 = 0
-2 - -1 = -1
-2 - 0 = -2
-2 - 1 = 1
-1 - -2 = 1
-1 - -1 = 0
-1 - 0 = -1
-1 - 1 = -2
0 - -2 = -2
0 - -1 = 1
0 - 0 = 0
0 - 1 = -1
1 - -2 = -1
1 - -1 = -2
1 - 0 = 1
1 - 1 = 0
This simulates an n bit integer operation:
#include <iostream>
#include <cstdlib>
template< typename T >
T sub_wrap(T a, T b, int nBits)
{
T topBit, mask, tmp;
topBit=T(1) << (nBits-1);
mask=(topBit << 1)-1;
tmp=((a&mask)+((~b+1)&mask))&mask;
if (tmp & topBit) tmp=-((~tmp&mask)+1);
return tmp;
}
int main(int argc, char* argv[])
{
std::cout << sub_wrap< int >(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]))
<< std::endl;
return 0;
}
Results:
$ ./sim 5 6 4
-1
$ ./sim 7 3 4
4
$ ./sim 7 -1 4
-8
$ ./sim -16 28 4
4
$ ./sim -16 28 5
-12
$ ./sim -16 28 6
20
Seems you miscalculated your type size by 1 bit.

Understanding this bitset implementation (C++)

I just got this frame for a sudoku solver, but I don't understand the syntax they've used and how I'm supposed to proceed. They call it a bitset, but upon searching for it I found nothing similar.
// This file contains a simple implementation of sets of
// digits between 1 and 9, called fields.
#ifndef __SUDOKU_FIELD_H__
#define __SUDOKU_FIELD_H__
#include <iostream>
#include <cassert>
#include "digit.h"
class Field {
private:
// Use integers for a bitset
unsigned int _digits;
// Number of digits in bitset
unsigned int _size;
public:
// Initialize with all digits between 1 and 9 included
Field(void)
: _digits((1 << 1) | (1 << 2) | (1 << 3) |
(1 << 4) | (1 << 5) | (1 << 6) |
(1 << 7) | (1 << 8) | (1 << 9)), _size(9) {}
// Return size of digit set (number of digits in set)
unsigned int size(void) const {
// FILL IN
}
// Test whether digit set is empty
bool empty(void) const {
// FILL IN
}
// Test whether set is assigned (that is, single digit left)
bool assigned(void) const {
// FILL IN
}
// Test whether digit d is included in set
bool in(digit d) const {
assert((d >= 1) && (d <= 9));
// FILL IN
}
// Return digit to which the set is assigned
digit value(void) const {
assert(assigned());
// FILL IN
}
// Print digits still included
void print(std::ostream& os) const;
// Remove digit d from set (d must be still included)
void prune(digit d) {
assert(in(d));
// FILL IN
}
// Assign field to digit d (d must be still included)
void assign(digit d) {
assert(in(d));
// FILL IN
}
};
// Print field
inline std::ostream&
operator<<(std::ostream& os, const Field& f) {
f.print(os); return os;
}
#endif
Obviously the //FILL IN's are for me to write, and the meaning of the bitset is 9 bits where all of them initially are set to 1. The question is how I manipulate or use them.
Oh, by the way, this is a digit:
#ifndef __SUDOKU_DIGIT_H__
#define __SUDOKU_DIGIT_H__
typedef unsigned char digit;
#endif
A "bitfield" is just an interpretation of a integer in memory as if it was a list of bits. You will be setting, testing and resetting bits in this integer individually, and the comments in the code tell you exactly what to do in each function.
You can use '&' and '|' for bitwise AND and OR, and '<<' and '>>' for shifting all bits to the left and right. This article can be very helpful to you: http://en.wikipedia.org/wiki/Bitwise_operation
This initialization sets the bits 1 - 9 of _digits to 1. The expression (1 << n) means 1 shifted n bits to the left. The expression a | b means a bit-wise or of a and b.
So, in detail, all of the expressions (1 << n) result in a bit-pattern with all zeroes and a 1 at the n th position, for 0 < n < 10. All of these are or'd together, to yield a bit-pattern bits 1 through 9 set to 1:
(1 << 1) 0010 |
(1 << 2) 0100 |
(1 << 3) 1000
======================
1110
(unused bits not shown)
4 bits:
0000
1 in binary is:
0001
Shifting is used to choose a single bit:
0001 << 0 = 0001 // first bit
0001 << 1 = 0010 // second bit
0001 << 2 = 0100 // third bit
Or is used to set individual bits:
0000 | 0100 = 0100
And is used to retrieve bits:
0111 & 0001 = 0001
This is how bitsets work.
Example:
unsigned int x = 0;
x |= 1 << 4; // set 5th bit
x |= 1 << 3; // set 4th bit
x |= 0x3; // set first 2 bits - 0x3 = 0011
unsigned int b = true;
x |= b << 7; // set 8th bit to value of b
if (x & (1 << 2)) { // check if 3rd bit is true
// ...
}
b = (x >> 3) & 1; // set b to value of 4th bit
Here is a way to count number of bits, along with other helpful algorithms:
unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
v &= v - 1; // clear the least significant bit set
}

C++ how to know if number ends with some bit pattern

I want to know if a number ends with some predefined bit patterns.
for example
i want to know if a number N end with B
where, N is any number
and B is also any number
for example
if N = 01011100
B = 100 then this C++ function should return 1 here in this case 1
if N = 01011100
B = 101 then this function should return 0
:)
For the first case:
unsigned n = 0x5C;
unsigned m = 0x7; // "mask"
unsigned b = 0x4;
if ((n & m)==b) {
...do something...
}
Here's how it works:
01011100 n
00000111 m
00000100 n & m (bitand operator)
00000100 b
If you know number of bits in B, then you need to build a pattern with this number of bits as 1. Supposing int has 32 bits on your system:
unsigned int mask = 0xFFFFFFFF >> (32 - numberOfBitsInB);
if (N & mask == B)
printf("%d ends with %d\n", N, B);
else
printf("Nope");
You can also compute number of bits in B via:
int tmpB = B;
int numberOfBitsInB = 0;
while (tmpB)
{
numberOfBitsInB++;
tmpB >>= 1;
}
unsigned int mask = ~0 >> (sizeof(unsigned int) * 8 - num_bits_in_B);
if (N & Bitmask == B)
printf("%d ends with %d\n", N, B);
else
printf("Nope");
Use the method suggested by #Benoit above to compute the number of bits in B.
It is possible to generate a mask for any length bit pattern. Here is a C example. This would prevent you from having to hardcode 0x7 if you would like to check for more than 3 bits matching.
bool bitPattern(int N, int B)
{
int shift = 0;
int mask = 0x0;
while(B >> shift++ > 0) mask |= 0x01 << shift-1;
return (N & mask) == B;
}
int main(int argc, char *argv[]) {
printf("01011100 ends with 100 ? %s\n", bitPattern(0x5C, 0x04) ? "Yes" : "No");
printf("01011100 ends with 101 ? %s\n", bitPattern(0x5C, 0x05) ? "Yes" : "No");
}

How to perform multiplication, using bitwise operators?

I am working through a problem which i was able to solve, all but for the last piece - i am not sure how can one do multiplication using bitwise operators:
0*8 = 0
1*8 = 8
2*8 = 16
3*8 = 24
4*8 = 32
Can you please recommend an approach to solve this?
To multiply by any value of 2 to the power of N (i.e. 2^N) shift the bits N times to the left.
0000 0001 = 1
times 4 = (2^2 => N = 2) = 2 bit shift : 0000 0100 = 4
times 8 = (2^3 -> N = 3) = 3 bit shift : 0010 0000 = 32
etc..
To divide shift the bits to the right.
The bits are whole 1 or 0 - you can't shift by a part of a bit thus if the number you're multiplying by is does not factor a whole value of N
ie.
since: 17 = 16 + 1
thus: 17 = 2^4 + 1
therefore: x * 17 = (x * 16) + x in other words 17 x's
thus to multiply by 17 you have to do a 4 bit shift to the left, and then add the original number again:
==> x * 17 = (x * 16) + x
==> x * 17 = (x * 2^4) + x
==> x * 17 = (x shifted to left by 4 bits) + x
so let x = 3 = 0000 0011
times 16 = (2^4 => N = 4) = 4 bit shift : 0011 0000 = 48
plus the x (0000 0011)
ie.
0011 0000 (48)
+ 0000 0011 (3)
=============
0011 0011 (51)
Edit: Update to the original answer. Charles Petzold has written a fantastic book 'Code' that will explain all of this and more in the easiest of ways. I thoroughly recommend this.
To multiply two binary encoded numbers without a multiply instruction.
It would be simple to iteratively add to reach the product.
unsigned int mult(x, y)
unsigned int x, y;
{
unsigned int reg = 0;
while(y--)
reg += x;
return reg;
}
Using bit operations, the characteristic of the data encoding can be exploited.
As explained previously, a bit shift is the same as multiply by two.
Using this an adder can be used on the powers of two.
// multiply two numbers with bit operations
unsigned int mult(x, y)
unsigned int x, y;
{
unsigned int reg = 0;
while (y != 0)
{
if (y & 1)
{
reg += x;
}
x <<= 1;
y >>= 1;
}
return reg;
}
You'd factor the multiplicand into powers of 2.
3*17 = 3*(16+1) = 3*16 + 3*1
... = 0011b << 4 + 0011b
public static int multi(int x, int y){
boolean neg = false;
if(x < 0 && y >= 0){
x = -x;
neg = true;
}
else if(y < 0 && x >= 0){
y = -y;
neg = true;
}else if( x < 0 && y < 0){
x = -x;
y = -y;
}
int res = 0;
while(y!=0){
if((y & 1) == 1) res += x;
x <<= 1;
y >>= 1;
}
return neg ? (-res) : res;
}
I believe this should be a left shift. 8 is 2^3, so left shift 3 bits:
2 << 3 = 8
-(int)multiplyNumber:(int)num1 withNumber:(int)num2
{
int mulResult =0;
int ithBit;
BOOL isNegativeSign = (num1<0 && num2>0) || (num1>0 && num2<0) ;
num1 = abs(num1);
num2 = abs(num2);
for(int i=0;i<sizeof(num2)*8;i++)
{
ithBit = num2 & (1<<i);
if(ithBit>0){
mulResult +=(num1<<i);
}
}
if (isNegativeSign) {
mulResult = ((~mulResult)+1 );
}
return mulResult;
}
I have just realized that this is the same answer as the previous one. LOL sorry.
public static uint Multiply(uint a, uint b)
{
uint c = 0;
while(b > 0)
{
c += ((b & 1) > 0) ? a : 0;
a <<= 1;
b >>= 1;
}
return c;
}
I was working on a recursive multiplication problem without the * operator and came up with a solution that was informed by the top answer here.
I thought it was worth posting because I really like the explanation in the top answer here, but wanted to expand on it in a way that:
Had a function representation.
Handled cases where your "remainder" was arbitrary.
This only handles positive integers, but you could wrap it in a check for negatives like some of the other answers.
def rec_mult_bitwise(a,b):
# Base cases for recursion
if b == 0:
return 0
if b == 1:
return a
# Get the most significant bit and the power of two it represents
msb = 1
pwr_of_2 = 0
while True:
next_msb = msb << 1
if next_msb > b:
break
pwr_of_2 += 1
msb = next_msb
if next_msb == b:
break
# To understand the return value, remember:
# 1: Left shifting by the power of two is the same as multiplying by the number itself (ie x*16=x<<4)
# 2: Once we've done that, we still need to multiply by the remainder, hence b - msb
return (a << pwr_of_2) + rec_mult_bitwise(a, b - msb)
Using Bitwise operator reduces the time complexity.
In cpp:
#include<iostream>
using name space std;
int main(){
int a, b, res = 0; // read the elements
cin>>a>>b;
// find the small number to reduce the iterations
small = (a<b)?a:b; // small number using terinary operator
big = (small^a)?a:b; // big number using bitwise XOR operator
while(small > 0)
{
if(small & 1)
{
res += big;
}
big = big << 1; // it increases the number << is big * (2 power of big)
small = small >> 1; // it decreases the number >> is small / (2 power of small)
}
cout<<res;
}
In Python:
a = int(input())
b = int(input())
res = 0
small = a if(a < b) else b
big = a if(small ^ a) else b
def multiplication(small, big):
res = 0
while small > 0:
if small & 1:
res += big
big = big << 1
small = small >> 1
return res
answer = multiplication(small, big)
print(answer)
def multiply(x, y):
return x << (y >> 1)
You would want to halve the value of y, hence y shift bits to the right once (y >> 1) and shift the bits again x times to the left to get your answer x << (y >> 1).