(ptr + n-1) & -n what does this expression do? [duplicate] - c++

This question already has answers here:
How to align a pointer in C
(6 answers)
Closed 6 years ago.
When I browsing c++ header files of opencv, It happened to see the construct (ptr + n-1) & -n in alignPtr function. The complete function as follows
/*!
Aligns pointer by the certain number of bytes
This small inline function aligns the pointer by the certain number of bytes by shifting
it forward by 0 or a positive offset.
*/
template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
{
return (_Tp*)(((size_t)ptr + n-1) & -n);
}
Can you explain how it works?

In this expression its implicit that n is a power of 2 such as 2, 4, 8 etc. Lets say that n is 2^m
In a twos complement binary system:
-2 is ...11110
-4 is ...11100
-8 is ...11000
In general, n = -2^m has a representation with exactly the m rightmost digits being zero.
This means, if we take any number and & it with -2^m then it will be returned with the m rightmost digits being zero, and the other digits retained, which makes the answer a multiple of 2^m.
This means the expression x & -2^m will effectively "floor" the number to the largest multiple of 2^m that is less than or equal to x.
The addition of (n - 1) that is being done:
(x + (n-1)) & -2^m
effectively changes this from a "floor" to a "rounding".

Related

K & R : Need Explanation in understanding this C code [duplicate]

This question already has answers here:
Need help understanding "getbits()" method in Chapter 2 of K&R C
(6 answers)
Closed 6 years ago.
In the K&R book in chapter 2.9, I am stuck on understanding this sample function getbits()
getbits(x,p,n)
Returns the (right-adjusted) n-bit field of x that begins at position p. Here's the function body
/* getbits: get n bits from from position p */
unsigned getbits(unsigned x, int p, int n)
{
return (x >> (p+1-n)) & ~(~0 << n);
}
I am actually not facing problems with the bitwise operators but I can't actually get the question. I am stuck on understanding the question mainly not solving it.
Ultimately "What do we need to find in this function".
It just shifts the bits right by p+1-n bits (to make the required field right-justified), then masks out all but the bottom n bits. Here is an expanded version, which may be easier to understand:
unsigned getbits(unsigned x, int p, int n)
{
unsigned x_right = (x >> (p+1-n)); // shift right to make required bits right-justified
unsigned mask = ~(~0 << n); // create n bit mask
return x_right & mask; // return required bits
}
Drawing a binary representation usually helps for such cases.
For example: taking 3 bits from position 5:
X: 101010101
--^
p
It shifts:
X: 1010
^
p
And then masks:
X: 010
--^
p

Bitwise NOT operator returning unexpected and negative value? [duplicate]

This question already has answers here:
Why is the output -33 for this code snippet
(3 answers)
Closed 9 years ago.
I'm trying to get the value of an integer using Bitwise NOT, but i'm not getting what i expected.
#include <stdio.h>
int main(){
int i = 16;
int j = ~i;
printf("%d", j);
return 0;
}
Isn't 16 supposed to be:
00000000000000000000000000010000
So ~16 is supposed to be:
11111111111111111111111111101111
Why i'm not getting what i expected and why the result is negative?
This is what i'm trying to do:
I have a number for exemple 27 which is:
00000000000000000000000000011011
And want to check every bit if it's 1 or 0.
So i need to get for exemple this value
11111111111111111111111111110111
The use second one to check if the 3rd bit of the first is set to 1.
Although there are pedantic points which can be made about compiler behaviour, the simple answer is that a signed int with the top bit set is a negative number.
So if you do something which sets the top bit of an int (a signed int, not an unsigned one), then ask the tools/library to show you the value of that int, you'll see a negative number.
This is not a universal truth, but it's a good approximation to it for most modern systems.
Note that it's printf which is making the representation here - because %d formats numbers as signed. %u may give the result you're expecting. Just changing the types of the variables won't be enough, because printf doesn't know anything about the types of its arguments.
I would say that as a general rule of thumb, if you're doing bit-twiddling, then use unsigned ints and display them in hexadecimal. Life will be simpler that way, and it most generally fits with the intent. (Fancy accelerated maths tricks are an obvious exception)
And want to check every bit if it's 1 or 0.
To check an individual bit, you don't NOT the number, you AND it with an appropriate bit mask:
if ((x & 1) != 0) ... // bit 0 is 1
if ((x & 2) != 0) ... // bit 1 is 1
if ((x & 4) != 0) ... // bit 2 is 1
if ((x & 8) != 0) ... // bit 3 is 1
...
if ((x & (1 << n)) != 0) ... // bit n is 1
...
if ((x & 0x80000000) != 0) ... // bit 31 is 1
If you want to get ones' complement of a number, you need to put that number into an unsigned variable and show it as so.
In C it would be:
unsigned int x = ~16;
printf("%u\n", x);
and you will get 4294967279.
But if you are just trying to get the negative number of a certain one, put the - operator before it.
EDIT: To check whether a bit is 0 or 1, you have to use the bitwise AND.
In two-complement arithmetic to get a reverse number (for example for value 16 to get value -16) you need reverse each bit and add 1.
In your example, to get -16 from 16 that is represented as
00000000000000000000000000010000
you need reverse each bit. You will get
11111111111111111111111111101111
Now you must add 1 and you will get
11111111111111111111111111110000
As you can see if you add these two values, you will get 0. It proves that you did all correctly.

What does this exactly mean?

Could anyone please explain me what exactly the following line of code produce?
i = 1<<(sizeof(n) * 8 - 1);
You can assume whatever value you want for 'n'. I am trying to implement an 8 bit multiplication program using Booths algorithm.
Let's break it down:
sizeof(n) delivers the size of the type of variable n. For an int variable n on a 32 bit system, this would e.g. be 4 (bytes). See the sizeof documentation e.g. here: http://en.cppreference.com/w/cpp/keyword/sizeof)
* 8 -> multiplication by the number of bits in one byte -> i.e. sizeof(n) * 8 delivers the number of bits necessary for n.
<< is the shiftleft operator. It will shift the first operand to the left by the amount of bits specified by the second operand (see here: http://en.wikipedia.org/wiki/Logical_shift); it's the logical shift, meaning that bits shifted in from the right are filled up with zeroes.
The full expression therefore delivers an expresssion with the highest bit representable by the variable n set to 1.
Example (assuming n now to be of type char, and assuming the size of char as the typical 1 byte):
sizeof(char) = 1
=> sizeof(char) * 8 - 1 = 7
=> 1 << 7 = 10000000

Counting number of bits: How does this line work ? n=n&(n-1); [duplicate]

This question already has answers here:
n & (n-1) what does this expression do? [duplicate]
(4 answers)
Closed 6 years ago.
I need some explanation how this specific line works.
I know that this function counts the number of 1's bits, but how exactly this line clears the rightmost 1 bit?
int f(int n) {
int c;
for (c = 0; n != 0; ++c)
n = n & (n - 1);
return c;
}
Can some explain it to me briefly or give some "proof"?
Any unsigned integer 'n' will have the following last k digits: One followed by (k-1) zeroes: 100...0
Note that k can be 1 in which case there are no zeroes.
(n - 1) will end in this format: Zero followed by (k-1) 1's: 011...1
n & (n-1) will therefore end in 'k' zeroes: 100...0 & 011...1 = 000...0
Hence n & (n - 1) will eliminate the rightmost '1'. Each iteration of this will basically remove the rightmost '1' digit and hence you can count the number of 1's.
I've been brushing up on bit manipulation and came across this. It may not be useful to the original poster now (3 years later), but I am going to answer anyway to improve the quality for other viewers.
What does it mean for n & (n-1) to equal zero?
We should make sure we know that since that is the only way to break the loop (n != 0).
Let's say n=8. The bit representation for that would be 00001000. The bit representation for n-1 (or 7) would be 00000111. The & operator returns the bits set in both arguments. Since 00001000 and 00000111 do not have any similar bits set, the result would be 00000000 (or zero).
You may have caught on that the number 8 wasn't randomly chosen. It was an example where n is power of 2. All powers of 2 (2,4,8,16,etc) will have the same result.
What happens when you pass something that is not an exponent of 2? For example, when n=6, the bit representation is 00000110 and n-1=5 or 00000101.The & is applied to these 2 arguments and they only have one single bit in common which is 4. Now, n=4 which is not zero so we increment c and try the same process with n=4. As we've seen above, 4 is an exponent of 2 so it will break the loop in the next comparison. It is cutting off the rightmost bit until n is equal to a power of 2.
What is c?
It is only incrementing by one every loop and starts at 0. c is the number of bits cut off before the number equals a power of 2.

Getting "carry" in x + y [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Best way to detect integer overflow in C/C++
If I have an expression x + y (in C or C++) where x and y are both of type uint64_t which causes an integer overflow, how do I detect how much it overflowed by (the carry), place than in another variable, then compute the remainder?
The remainder will already be stored in the sum of x + y, assuming you are using unsigned integers. Unsigned integer overflow causes a wrap around ( signed integer overflow is undefined ). See standards reference from Pascal in the comments.
The overflow can only be 1 bit. If you add 2 64 bit numbers, there cannot be more than 1 carry bit, so you just have to detect the overflow condition.
For how to detect overflow, there was a previous question on that topic: best way to detect integer overflow.
For z = x + y, z stores the remainder. The overflow can only be 1 bit and it's easy to detect. If you were dealing with signed integers then there's an overflow if x and y have the same sign but z has the opposite. You cannot overflow if x and y have different signs. For unsigned integers you just check the most significant bit in the same manner.
The approach in C and C++ can be quite different, because in C++ you can have operator overloading work for you, and wrap the integer you want to protect in some kind of class (for which you would overload the necessary operators. In C, you would have to wrap the integer you want to protect in a structure (to carry the remainder as well as the result) and call some function to do the heavy lifting.
Other than that, the approach in the two languages is the same: depending on the operation you want to perform (adding, in your example) you have to figure out the worst that could happen and handle it.
In the case of adding, it's quite simple: if the sum of the two is going to be greater than some maximum value (which will be the case if the difference of that maximum value M and one of the operands is greater than the other operand) you can calculate the remainder - the part that's too big: if ((M - O1) > O2) R = O2 - (M - O1) (e.g. if M is 100, O1 is 80 and O2 is 30, 30 - (100 - 80) = 10, which is the remainder).
The case of subtraction is equally simple: if your first operand is smaller than the second, the remainder is the second minus the first (if (O1 < O2) { Rem = O2 - O1; Result = 0; } else { Rem = 0; Result = O1 - O2; }).
It's multiplication that's a bit more difficult: your safest bet is to do a binary multiplication of the values and check that your resulting value doesn't exceed the number of bits you have. Binary multiplication is a long multiplication, just like you would do if you were doing a decimal multiplication by hand on paper, so, for example, 12 * 5 is:
0110
0100
====
0110
0
0110
0
++++++
011110 = 40
if you'd have a four-bit integer, you'd have an overflow of one bit here (i.e. bit 4 is 1, bit 5 is 0. so only bit 4 counts as an overflow).
For division you only really need to care about division by 0, most of the time - the rest will be handled be your CPU.
HTH
rlc