Is using bit wise makes the code unreadable [duplicate] - c++

This question already has answers here:
Which is better option to use for dividing an integer number by 2?
(22 answers)
Closed 6 years ago.
I have encountered many occasions when I have to use between division operator(divide by 2) or the right shift operator(>>) but I tend to use the division operator assuming that use of bit wise operator will make my code less readable. Is my assumption true?
Is it good practice to use left shift operator and right shift operator in production code instead of multiply by 2 or divide by 2.

Using the bitwise operators for multiplication or division by 2 is utter madness.
The behaviour of << is undefined for negative signed types.
<< and >> have lower precedence than addition and subtraction so it messes up your expressions.
It's unnecessarily obfuscating.
Trust a modern compiler to optimise appropriately.

Integer division by constants is routinely optimized to bit shifts (if by powers of two), multiplication by the "integral reciprocal" and all kind of tricks, so performance should not be a concern.
What matters is to clearly express intent. If you are operating on integers "as numbers" and you divide by something that just happens to be a power of 2 use the division operator.
int mean(int a, int b) {
return (a+b)/2; // yes overflow blah blah
}
If instead you are operating on integers as bitfields - for example, you are unpacking a nibble and you need to right shift by 4 to move it in "low" position, or you need to explicitly set some bit -, then use bitwise operators.
void hex_byte(unsigned char byte, char *out) {
out[0]=byte>>4;
out[1]=byte&0xf;
}
unsigned set_bit(unsigned in, unsigned n) {
return in | (1<<n);
}
In general, most often you'll use division on signed integers, bitwise operators on unsigned ones.

Related

Represent Integers with 2000 or more digits [duplicate]

This question already has answers here:
Handling large numbers in C++?
(10 answers)
Closed 7 years ago.
I would like to write a program, which could compute integers having more then 2000 or 20000 digits (for Pi's decimals). I would like to do in C++, without any libraries! (No big integer, boost,...). Can anyone suggest a way of doing it? Here are my thoughts:
using const char*, for holding the integer's digits;
representing the number like
( (1 * 10 + x) * 10 + x )...
The obvious answer works along these lines:
class integer {
bool negative;
std::vector<std::uint64_t> data;
};
Where the number is represented as a sign bit and a (unsigned) base 2**64 value.
This means the absolute value of your number is:
data[0] + (data[1] << 64) + (data[2] << 128) + ....
Or, in other terms you represent your number as a little-endian bitstring with words as large as your target machine can reasonably work with. I chose 64 bit integers, as you can minimize the number of individual word operations this way (on a x64 machine).
To implement Addition, you use a concept you have learned in elementary school:
a b
+ x y
------------------
(a+x+carry) (b+y reduced to one digit length)
The reduction (modulo 2**64) happens automatically, and the carry can only ever be either zero or one. All that remains is to detect a carry, which is simple:
bool next_carry = false;
if(x += y < y) next_carry = true;
if(prev_carry && !++x) next_carry = true;
Subtraction can be implemented similarly using a borrow instead.
Note that getting anywhere close to the performance of e.g. libgmp is... unlikely.
A long integer is usually represented by a sequence of digits (see positional notation). For convenience, use little endian convention: A[0] is the lowest digit, A[n-1] is the highest one. In general case your number is equal to sum(A[i] * base^i) for some value of base.
The simplest value for base is ten, but it is not efficient. If you want to print your answer to user often, you'd better use power-of-ten as base. For instance, you can use base = 10^9 and store all digits in int32 type. If you want maximal speed, then better use power-of-two bases. For instance, base = 2^32 is the best possible base for 32-bit compiler (however, you'll need assembly to make it work optimally).
There are two ways to represent negative integers, The first one is to store integer as sign + digits sequence. In this case you'll have to handle all cases with different signs yourself. The other option is to use complement form. It can be used for both power-of-two and power-of-ten bases.
Since the length of the sequence may be different, you'd better store digit sequence in std::vector. Do not forget to remove leading zeroes in this case. An alternative solution would be to store fixed number of digits always (fixed-size array).
The operations are implemented in pretty straightforward way: just as you did them in school =)
P.S. Alternatively, each integer (of bounded length) can be represented by its reminders for a set of different prime modules, thanks to CRT. Such a representation supports only limited set of operations, and requires nontrivial convertion if you want to print it.

Difference between (n&1) and n&1 [duplicate]

This question already has answers here:
Operator precedence (bitwise '&' lower than '==')
(3 answers)
Closed 8 years ago.
I was trying to solve a Counter Game problem:
"Louise and Richard play a game. They have a counter set to N. Louise gets the first turn and the turns alternate thereafter. In the game, they perform the following operations.
If N is not a power of 2, they reduce the counter by the largest power of 2 less than N.
If N is a power of 2, they reduce the counter by half of N.
The resultant value is the new N which is again used for subsequent operations.
The game ends when the counter reduces to 1, i.e., N == 1, and the last person to make a valid move wins.
Given N, your task is to find the winner of the game."
To solve the question, I implemented bit manipulation, and got accepted:
#include <iostream>
#include <cstdio>
int main() {
long long unsigned int n, tmp;
int cnt, t;
scanf("%d", &t);
while(t--) {
scanf("%llu", &n), tmp=n;
cnt=0;
while(tmp) tmp&=tmp-1, cnt++;
cnt--;
while((n&1)==0) n>>=1, cnt++;
if(cnt%2==0) printf("Richard\n");
else printf("Louise\n");
}
return 0;
}
However, during the coding i coded while(n&1==false) instead of while((n&1)==false), thus could not get desired result. Coding while(!(n&1)) gave expected result, but that(!a instead of a==false) was bad practice due to some sources(I forgot them) I have read online. And I know the difference between while(!n&1) and while(!(n&1)), but I did not know while(n&1==false) and while((n&1)==false). Learnt the latter was and is dissimilar, and may I ask the distinction, please?
This is considered by many a design mistake of C.
While it's natural that a logical-and operation should have lower precedence than equality comparison the same is much more questionable for bitwise-and because bitwise operations are naturally closer to math operations.
The same design error has been inherited by C++ for backward compatibility.
A good rule is always parenthesize bitwise operations to avoid surprises.
As you can see here, the precedence of == is above the precedence of &.
Therefore n&1==false is interpreted as n&(1==false) not (n&1)==false, so you need the parentheses.
== has higher priority in C++ than & (source).
Thus while(n&1==false) is treated as while (n & (1 == false)) which actually is while (n & 0).

Distinguish zero and negative zero

I have run into a situation in my code where a function returns a double, and it is possible for this double to be a zero, a negative zero, or another value entirely. I need to distinguish between zero and negative zero, but the default double comparison does not. Due to the format of doubles, C++ does not allow for comparison of doubles using bitwise operators, so I am unsure how to procede. How can I distinguish between the two?
Call std::signbit() to determine the state of the sign bit.
Due to the format of doubles, C++ does not allow for comparison of doubles using bitwise operators, so I am unsure how to procede.
First off, C++ doesn't mandate any standard for float/double types.
Assuming you're talking about IEEE 754's binary32 and binary64 formats, they're specifically designed to maintain their order when their bit patterns are interpreted as integers so that a non-FPU can sort them; this is the reason they have a biased exponent.
There're many SO posts discussing such comparisons; here's the most relevant one. A simple check would be
bool is_negative_zero(float val)
{
return ((val == 0.0f) && std::signbit(val));
}
This works since 0.0f == -0.0f, although there're places where the sign makes a difference like atan2 or when dividing by -0 as opposed to +0 leads to the respective infinities.
To test explicitly for a == -0 in C do the following:
if (*((long *)&a) == 0x8000000000000000) {
// a is -0
}

Bit shifting and assignment [duplicate]

This question already has answers here:
Why doesn't left bit-shift, "<<", for 32-bit integers work as expected when used more than 32 times?
(10 answers)
Closed 9 years ago.
This is sort of driving me crazy.
int a = 0xffffffff;
int b = 32;
cout << (a << b) << "\n";
cout << (0xffffffff << 32) << "\n";
My output is
-1
0
Why am I not getting
0
0
Undefined behavior occurs when you shift a value by a number of bits which is not less than its size (e.g, 32 or more bits for a 32-bit integer). You've just encountered an example of that undefined behavior.
The short answer is that, since you're using an implementation with 32-bit int, the language standard says that a 32-bit shift is undefined behavior. Both the C standard (section 6.5.7) and the C++ standard (section 5.8) say
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
But if you want to know why:
Many computers have an instruction that can shift the value in a register, but the hardware only handles shift values that are actually needed. For instance, when shifting a 32 bit word, only 5 bits are needed to represent a shift value of 0 ... 31 and so the hardware may ignore higher order bits, and does on *86 machines (except for the 8086). So that compiler implementations could just use the instruction without generating extra code to check whether the shift value is too big, the authors of the C Standard (many of whom represented compiler vendors) ruled that the result of shifting by larger amounts is undefined.
Your first shift is performed at run time and it encounters this situation ... only the low order 5 bits of b are considered by your machine, and they are 0, so no shift happens. Your second shift is done at compile time, and the compiler calculates the value differently and actually does the 32-bit shift.
If you want to shift by an amount that may be larger than the number of bits in the thing you're shifting, you need to check the range of the value yourself. One possible way to do that is
#define LEFT_SHIFT(a, b) ((b) >= CHAR_BIT * sizeof(a)? 0 : (a) << (b))
C++ standard says ::
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
As GCC has no options to handle shifts by negative amounts or by amounts outside the width of the type predictably or trap on them; they are always treated as undefined.
So behavior is not defined.

Emulated Fixed Point Division/Multiplication

I'm writing a Fixedpoint class, but have ran into bit of a snag... The multiplication, division portions, I am not sure how to emulate. I took a very rough stab at the division operator but I am sure it's wrong. Here's what it looks like so far:
class Fixed
{
Fixed(short int _value, short int _part) :
value(long(_value + (_part >> 8))), part(long(_part & 0x0000FFFF)) {};
...
inline Fixed operator -() const // example of some of the bitwise it's doing
{
return Fixed(-value - 1, (~part)&0x0000FFFF);
};
...
inline Fixed operator / (const Fixed & arg) const // example of how I'm probably doing it wrong
{
long int tempInt = value<<8 | part;
long int tempPart = tempInt;
tempInt /= arg.value<<8 | arg.part;
tempPart %= arg.value<<8 | arg.part;
return Fixed(tempInt, tempPart);
};
long int value, part; // members
};
I... am not a very good programmer, haha!
The class's part is 16 bits wide (but expressed as a 32-bit long since I imagine it'd need the room for possible overflows before they're fixed) and the same goes for value which is the integer part. When the 'part' goes over 0xFFFF in one of it's operations, the highest 16 bits are added to 'value', and then the part is masked so only it's lowest 16 bits remain. That's done in the init list.
I hate to ask, but if anyone would know where I could find documentation for something like this, or even just the 'trick' or how to do those two operators, I would be very happy for it! I am a dimwit when it comes to math, and I know someone has had to do/ask this before, but searching google has for once not taken me to the promised land...
As Jan says, use a single integer. Since it looks like you're specifying 16 bit integer and fractional parts, you could do this with a plain 32 bit integer.
The "trick" is to realise what happens to the "format" of the number when you do operations on it. Your format would be described as 16.16. When you add or subtract, the format stays the same. When you multiply, you get 32.32 -- So you need a 64 bit temporary value for the result. Then you do a >>16 shift to get down to 48.16 format, then take the bottom 32 bits to get your answer in 16.16.
I'm a little rusty on the division -- In DSP, where I learned this stuff, we avoided (expensive) division wherever possible!
I'd recommend using one integer value instead of separate whole and fractional part. Than addition and subtraction are the integeral counterparts directly and you can simply use 64-bit support, which all common compilers have these days:
Multiplication:
operator*(const Fixed &other) const {
return Fixed((int64_t)value * (int64_t)other.value);
}
Division:
operator/(const Fixed &other) const {
return Fixed(((int64_t)value << 16) / (int64_t)other.value);
}
64-bit integers are
On gcc, stdint.h (or cstdint, which places them in std:: namespace) should be available, so you can use the types I mentioned above. Otherwise it's long long on 32-bit targets and long on 64-bit targets.
On Windows, it's always long long or __int64.
To get things up and running, first implement the (unary) inverse(x) = 1/x, and then implement a/b as a*inverse(b). You'll probably want to represent the intermediates as a 32.32 format.