What do "Non-Power-Of-Two Textures" mean? - c++

What do "Non-Power-Of-Two Textures" mean? I read this tutorial and I meet some binaries operations("<<", ">>", "^", "~"), but I don't understand what they are doing.
For example following code:
GLuint LTexture::powerOfTwo(GLuint num)
{
if (num != 0)
{
num--;
num |= (num >> 1); //Or first 2 bits
num |= (num >> 2); //Or next 2 bits
num |= (num >> 4); //Or next 4 bits
num |= (num >> 8); //Or next 8 bits
num |= (num >> 16); //Or next 16 bits
num++;
}
return num;
}
I very want to understand this operations. As well, I read this. Very short article. I want to see examples of using, but I not found. I did the test:
int a = 5;
a <<= 1; //a = 10
a = 5;
a <<= 2; //a = 20
a = 5;
a <<= 3; //a = 40
Okay, this like multiply on two, but
int a = 5;
a >>= 1; // a = 2 Whaat??

In C++, the <<= is the "left binary shift" assignment operator; the operand on the left is treated as a binary number, the bits are moved to the left, and zero bits are inserted on the right.
The >>= is the right binary shift; bits are moved to the right and "fall off" the right end, so it's like a division by 2 (for each bit) but with truncation. For negative signed integers, by the way, additional 1 bits are shifted in at the left end ("arithmetic right shift"), which may be surprising; for positive signed integers, or unsigned integers, 0 bits are shifted in at the left ("logical right shift").
"Powers of two" are the numbers created by successive doublings of 1: 2, 4, 8, 16, 32… Most graphics hardware prefers to work with texture maps which are powers of two in size.

As said in http://lazyfoo.net/tutorials/OpenGL/08_non_power_of_2_textures/index.php
powerOfTwo will take the argument and find nearest number that is power of two.
GLuint powerOfTwo( GLuint num );
/*
Pre Condition:
-None
Post Condition:
-Returns nearest power of two integer that is greater
Side Effects:
-None
*/
Let's test:
num=60 (decimal) and its binary is 111100
num--; .. 59 111011
num |= (num >> 1); //Or first 2 bits 011101 | 111011 = 111111
num |= (num >> 2); //Or next 2 bits 001111 | 111111 = 111111
num |= (num >> 4); //Or next 4 bits 000011 | 111111 = 111111
num |= (num >> 8); //Or next 8 bits 000000 | 111111 = 111111
num |= (num >> 16); //Or next 16 bits 000000 | 111111 = 111111
num++; ..63+1 = 64
output 64.
For num=5: num-1 =4 (binary 0100), after all num |= (num >> N) it will be 0111 or 7 decimal). Then num+1 is equal to 8.

As you should know the data in our computers is represented in the binary system, in which digits are either a 1 or a 0.
So for example number 10 decimal = 1010 binary. (1*2^3 + 0*2^2 + 1*2^1 + 0*2^0).
Let's go to the operations now.
Binary | OR means that wherever you have at least one 1 the output will be 1.
1010
| 0100
------
1110
~ NOT means negation i.e. all 0s become 1s and all 1s become 0s.
~ 1010
------
0101
^ XOR means you turn a pair of 1 and 0 into a 1. All other combinations leave a 0 as output.
1010
^ 0110
------
1100
Bit shift.
N >> x means we "slide" our number N, x bits to the right.
1010 >> 1 = 0101(0) // zero in the brackets is dropped,
since it goes out of the representation = 0101
1001 >> 1 = 0100(1) // (1) is dropped = 0100
<< behaves the same way, just the opposite direction.
1000 << 1 = 0001
Since in binary system numbers are represented as powers of 2, shifting a bit one or the other direction will result in multiplying or dividing by 2.

Let num = 36. First subtract 1, giving 35. In binary, this is 100011.
Right shift by 1 position gives 10001 (the rightmost digit disappears). Bitwise Or'ed with num gives:
100011
10001
-------
110011
Note that this ensures two 1's on the left.
Now right shift by 2 positions, giving 1100. Bitwise Or:
110011
1100
-------
111111
This ensures four 1's on the left.
And so on, until the value is completely filled with 1's from the leftmost.
Add 1 and you get 1000000, a power of 2.
This procedure always generates a power of two, and you can check that it is just above the initial value of num.

Related

How to interpret n & (n - 1) [duplicate]

I'm looking at some code which should be trivial -- but my math is failing me miserably here.
Here's a condition that checks if a number if a power of 2 using the following:
if((num != 1) && (num & (num - 1))) { /* make num pow of 2 */ }
My question is, how does using a bitwise AND between num and num - 1 determine if a number is a power of 2?
Any power of 2 minus 1 is all ones: (2 N - 1 = 111....b)
2 = 2^1. 2-1 = 1 (1b)
4 = 2^2. 4-1 = 3 (11b)
8 = 2^3. 8-1 = 7 (111b)
Take 8 for example. 1000 & 0111 = 0000
So that expression tests if a number is NOT a power of 2.
Well, the first case will check for 20 == 1.
For the other cases the num & (num - 1) comes into play:
That's saying if you take any number, and mask off the bits from one lower, you'll get one of two cases:
if the number is a power of two already, then one less will result in a binary number that only has the lower-order bits set. Using & there will do nothing.
Example with 8: 0100 & (0100 - 1) --> (0100 & 0011) --> 0000
if the number is not a power of two already, then one less will not touch the highest bit, so the result will be at least the largest power of two less than num.
Example with 3: 0011 & (0011 - 1) --> (0011 & 0010) --> 0010
Example with 13: 1101 & (1101 - 1) --> (1101 & 1100) --> 1100
So the actual expression finds everything that isn't a power of two, including 20.
Well,
if you have X = 1000 then x-1 = 0111. And 1000 && 0111 is 0000.
Each number X that is a power of 2 has an x-1 that has ones on the position x has zeroes. And a bitwise and of 0 and 1 is always 0.
If the number x is not a power of two, for example 0110. The x-1 is 0101 and the and gives 0100.
For all combinbations within 0000 - 1111 this leads to
X X-1 X && X-1
0000 1111 0000
0001 0000 0000
0010 0001 0000
0011 0010 0010
0100 0011 0000
0101 0100 0100
0110 0101 0100
0111 0110 0110
1000 0111 0000
1001 1000 1000
1010 1001 1000
1011 1010 1010
1100 1011 1000
1101 1100 1100
1110 1101 1100
1111 1110 1110
And there is no need for a separate check for 1.
I prefer this approach that relies on two's complement:
bool checkPowTwo(int x){
return (x & -x) == x;
}
Explained here nicely
Also the expression given considers 0 to be a power of 2. To fix that use
!(x & (x - 1)) && x; instead.
It determines whether integer is power of 2 or not. If (x & (x-1)) is zero then the number is power of 2.
For example,
let x be 8 (1000 in binary); then x-1 = 7 (0111).
if 1000
& 0111
---------------
0000
C program to demonstrate:
#include <stdio.h>
void main()
{
int a = 8;
if ((a&(a-1))==0)
{
printf("the bit is power of 2 \n");
}
else
{
printf("the bit is not power of 2\n");
}
}
This outputs the bit is power of 2.
#include <stdio.h>
void main()
{
int a = 7;
if ((a&(a-1))==0)
{
printf("the bit is power of 2 \n");
}
else
{
printf("the bit is not power of 2\n");
}
}
This outputs the bit is not power of 2.
Suppose n is the given number,
if n is power of 2 (n && !(n & (n-1)) will return 1 else return 0
When you decrement a positive integer by 1:
if it is zero, you get -1.
if its least significant bit is 1, this bit is set to 0, the other bits are unchanged.
otherwise, all the low order 0 bits are set to 1 and the lowest 1 bit if set to 0, the other bits are unchanged.
Case 1: x & (x - 1) is 0, yet x is not a power of 2, trivial counter example.
Cases 2 and 3: if x and x-1 have no bits in common, it means the other bits in both of the above cases are all zero, hence the number has a single 1 bit, hence it is a power of 2.
If x is negative, this test does not work for two's complement representation of signed integers as either decrementing overflows or x and x-1 have at least the sign bit in common, which means x & (x-1) is not zero.
To test for a power of 2 the code should be:
int is_power_of_2(unsigned x) {
return x && !(x & (x - 1));
}
#include <stdio.h>
void powerof2(int a);
int a;
int main()
{
while(1)
{
printf("Enter any no. and Check whether no is power of 2 or no \n");
scanf("%d",&a);
powerof2(a);
}
}
void powerof2(int a)
{
int count = 0;
int b=0;
while(a)
{
b=a%2;
a=a/2;
if(b == 1)
{ count++; }
}
if(count == 1)
{
printf("power of 2\n");
}
else
printf("not power of 2\n");
}
Following program in C will find out if the number is power of 2 and also find which power of 2, the number is.
#include<stdio.h>
void main(void)
{
unsigned int a;
unsigned int count=0
unsigned int check=1;
unsigned int position=0;
unsigned int temp;
//get value of a
for(i=0;i<sizeof(int)*8;i++)//no of bits depend on size of integer on that machine
{
temp = a&(check << i);
if(temp)
{
position = i;
count++;
}
}
if(count == 1)
{
printf("%d is 2 to the power of %d",a,position);
}
else
{
printf("Not a power of 2");
}
}
There are other ways to do this:-
if a number is a power of 2, only 1 bit will be set in the binary format
for example 8 is equivalent to 0x1000, substracting 1 from this, we get 0x0111.
End operation with the original number(0x1000) gives 0.
if that is the case, the number is a power of 2
void IsPowerof2(int i)
{
if(!((i-1)&1))
{
printf("%d" is a power of 2, i);
}
}
another way can be like this:-
If we take complement of a number which is a power of 2,
for example complement of 8 i.e 0x1000 , we get 0x0111 and add 1 to it, we get
the same number, if that is the case, that number is a power of 2
void IsPowerof2(int i)
{
if(((~1+1)&i) == 1)
{
printf("%d" is a power of 2,i):
}
}

0 minus 0 gives carryout of 1 in adder-subtractor circuit

In this adder-subtractor design with the "M" input as the flag for subtraction, 0 minus 0 seems to provide the incorrect Cout. Let's assume that we're only using one full adder here (ignore A1/B1, A2/B2, A3/B3) for simplicity, and M=1, A0=0, A1=0:
The full adder will get the inputs of:
0 (B0) XOR 1 (M) = 1
0 (A0) = 0
1 (M) = 1
This results in 1+1=0, with Cout = 1 - but Cout should equal 0 for a full adder:
I think inverting the final Cout will provide the correct result, but everywhere I look online for this adder-subtractor circuit has no inverter for the final Cout. Is this circuit supposed to have an inverter at the final Cout to fix this problem?
The carry out equal to 1 is perfectly normal in this case.
When you work with unsigned logic the carry out is used as an overflow flag: assuming you're working with 4-bits operands, the operation:
a = 1000, b = 1001 (Decimal a = 8, b = 9)
1000 +
1001 =
--------
1 0001
produces a carry out of 1'b1 because the result of 8+9 cannot be represented on 4 bits.
On the other hand, when working with signed logic the carry out signal loses its 'overflow' meaning. Let's make an example:
a = 0111, b = 0010 (Decimal a = 7, b = 2)
0111 +
0010 =
--------
0 1001
In this case the result is 1001, that is -7 in two's complement. It's obvious that we had an overflow, since we added two positive numbers and we got a negative one. The carry out, anyway, is equal to 0. As a last case, if we consider:
a = 1111, b = 0001 (Decimal a = -1, b = 1)
1111 +
0001 =
--------
1 0000
we see that even though the result is correct -1+1=0, the carry out is set.
To conclude, if you work in signed logic and you need to understand whether there was an overflow, you need to check the sign of the two operands against the result's one.
Both operands positive (MSB = 0) and result negative (MSB = 1): overflow
Both operands negative (MSB = 1) and result positive (MSB = 0): overflow
Any other case: no overflow

What is the logic to use bitwise operation in generating subsequences? [duplicate]

This question already has answers here:
What does the statement if (counter & (1<<j)) mean and how does it work?
(2 answers)
Closed last year.
I have an array, A=[1,2,3,4] (where n=4). I want to generate sub-sequences from this array.
Number of subsequences is (2^n -1)
Run from counter 0001 to 1111
for (int counter = 1; counter < 2^n; counter++)
{
for (int j = 0; j < n; j++)
{
Check if the jth bit in the counter is set. If set then print jth element from arr[]
if (counter & (1<<j))
cout << arr[j] << " ";
}
cout << endl;
}
}
can anyone explain me? How it works " counter & (1<
The logic goes like this. Say, like you put in the example, you have n = 4, and, to avoid confusion, let's say the array is A = [5, 7, 8, 9], for example. Then you want all the possible sequences containing some elements (at least one) from the original array. So you want a sequence containing only the first one, a sequence containing the first and the second, the first and the third, etc. Each printed sequence may or may not contain each of the elements in the array. So you could see it as something like this:
| 5 | 7 | 8 | 9 | Sequence
----------------- --------
| 1 | 0 | 0 | 0 | -> 5
| 1 | 1 | 0 | 0 | -> 5 7
| 1 | 0 | 1 | 0 | -> 5 8
...
That is, each sequence can be expressed as a list of bits, each indicating whether each member of the array is included.
In this loop:
for (int counter = 1; counter < 2^n; counter++)
The program iterates from 1 to 2^n - 1, that is 15 in this case. So the values that you get for counter are:
Dec Binary
--- ------
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
If you look closely, you will see that we have all the possible sequences of four elements composed of 0 and 1 in binary (except 0000, which would be the empty sequence and does not interest us). In this loop:
for (int j = 0; j < n; j++)
The program just goes through each bit of counter, from 0 (the rightmost) to n - 1 and whenever it finds a 1 it outputs the corresponding array element. The condition:
if (counter & (1<<j))
Simply computes the number 1<<j which is 1 plus j number of zeros at its right (so, for example, for j = 0 it would be 1 and for j = 2 it would be 100) and then a bitwise and operation, so it basically "filters" the j-th bit only (e.g. 1101 & 100 = 0100), and if the result is not zero then it means there was a one, and so arr[j] must be printed.
Obviously, the problem with the function is that it is limited to the number of bits that the variable counter can hold. That depends on its declared type and your architecture/compiler, but typically it will be either 32 or 64.

How does condition statement work with bit-wise operators?

I tried to understand how if condition work with bitwise operators.
A way to check if a number is even or odd can be done by:
#include <iostream>
#include <string>
using namespace std;
string test()
{
int i = 8; //a number
if(i & 1)
return "odd";
else
return "even";
}
int main ()
{
cout << test();
return 0;
}
The Part I don't understand is how the if condition work. In this case if i = 8 then the in If statement it is doing 1000 & 1 which should gives back 1000 which equal 8.
If i = 7, then in if statement it should be doing 111 & 1 which gives back 111 which equal 7
Why is it the case that if(8) will return "even" and if(7) return "odd"? I guess I want to understand what the if statement is checking to be True and what to be False when dealing with bit-wise operators.
Just A thought when I wrote this question down is it because it's actually doing
for 8: 1000 & 0001 which gives 0
for 7: 0111 & 0001 which gives 1?
Yes, you are right in the last part. Binary & and | are performed bit by bit. Since
1 & 1 == 1
1 & 0 == 0
0 & 1 == 0
0 & 0 == 0
we can see that:
8 & 1 == 1000 & 0001 == 0000
and
7 & 1 == 0111 & 0001 == 0001
Your test function does correctly compute whether a number is even or odd though, because a & 1 tests whether there is a 1 in the 1s place, which there only is for odd numbers.
Actually, in C, C++ and other major programming languages the & operator do AND operations in each bit for integral types. The nth bit in a bitwise AND is equal to 1 if and only if the nth bit of both operands are equal to 1.
For example:
8 & 1 =
1000 - 8
0001 - 1
----
0000 - 0
7 & 1 =
0111 - 7
0001 - 1
----
0001 - 1
7 & 5 =
0111 - 7
0101 - 5
----
0101 - 5
For this reason doing a bitwise AND between an even number and 1 will always be equal 0 because only odd numbers have their least significant bit equal to 1.
if(x) in C++ converts x to boolean. An integer is considered true iff it is nonzero.
Thus, all if(i & 1) is doing is checking to see if the least-significant bit is set in i. If it is set, i&1 will be nonzero; if it is not set, i&1 will be zero.
The least significant bit is set in an integer iff that integer is odd, so thus i&1 is nonzero iff i is odd.
What you say the code is doing is actually how bit-wise operators are supposed to work. In your example of (8 & 1):
1000 & 0001 = 0000
because in the first value, the last bit is set to 0, while in the second value, the last bit is set to 1. 0 & 1 = 0.
0111 & 0001 = 0001
In both values, the last bit is set to 1, so the result is 1 since 1 & 1 = 1.
The expression i & 1, where i is an int, has type int. Its value is 1 or 0, depending on the value of the low bit of i. In the statement if(i & 1), the result of that expression is converted to bool, following the usual rule for integer types: 0 becomes false and non-zero becomes true.

How does this implementation of bitset::count() work?

Here's the implementation of std::bitset::count with MSVC 2010:
size_t count() const
{ // count number of set bits
static char _Bitsperhex[] = "\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4";
size_t _Val = 0;
for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
for (_Ty _Wordval = _Array[_Wpos]; _Wordval != 0; _Wordval >>= 4)
_Val += _Bitsperhex[_Wordval & 0xF];
return (_Val);
}
Can someone explain to me how this is working? what's the trick with _Bitsperhex?
_Bitsperhex contains the number of set bits in a hexadecimal digit, indexed by the digit.
digit: 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
value: 0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4
index: 0 1 2 3 4 5 6 7 8 9 A B C D E F
The function retrieves one digit at a time from the value it's working with by ANDing with 0xF (binary 1111), looks up the number of set bits in that digit, and sums them.
_Bitsperhex is a 16 element integer array that maps a number in [0..15] range to the number of 1 bits in the binary representation of that number. For example, _Bitsperhex[3] is equal to 2, which is the number of 1 bits in the binary representation of 3.
The rest is easy: each multi-bit word in internal array _Array is interpreted as a sequence of 4-bit values. Each 4-bit value is fed through the above _Bitsperhex table to count the bits.
It is a slightly different implementation of the lookup table-based method described here: http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable. At the link they use a table of 256 elements and split 32-bit words into four 8-bit values.