Bit arithmetic in C - c

Say we have 11101111 stored in the address address, how would I add the first 4 bits to the last 4 bits?
My prof showed us we can do this (*address)/16 + (*address)%16 but I don't understand why it works. Can someone explain where the division and modulo with 16 come from?

#VanGo, See to perform operation on bits, you have to learn bitwise operator first.
I am explaining your problem here.
11101111 (is in binary form) and is equivalent to 239 (in decimal).
Now you have to add 1110 in 1111. In order to get these two pair of 4 bits from 11101111, you have to perform bitwise operation on 11101111.
To get higher 4 bits, shift 11101111 four times from left to right.
*address >> 4 :- is equal to *address/16
internally compiler convert *address>>4 into (*address)/(2 pow 4).
To get lower 4 bits, either perform (*address)&0x0f or (*address)%16. Both operation will clear all bits except lower 4 bits.
printf(".....%d\n",(((*address)>>4) + ((*address)&0x0f)));
hope it helps you.

Related

what does "if(( number >> 1) <<1==number)" mean?

c program to check odd or even without using modulus operator
We can check a number is even or odd without using modulus and division operator in c program
The another method is using shift operators
number >> 1) <<1==number then it is even number,can someone explaain this?
A right shift by x is essentially a truncating division by 2x.
A left shift by x is essentially a multiplication by 2x.
6 ⇒ 3 ⇒ 6
7 ⇒ 3 ⇒ 6
If this produces the original number, it's even.
An unsigned number is odd if its lowest (1) bit is 1. What this does is shift right by 1, and then right by one, effictively zeroing out this first bit. If that bit was already a 0 (i.e. the number is even), then the number doesn't change and the == passes. If it was a 1 then its now a zero and the equality check fails.
A better, more obvious implementation of this logic would be:
if((number & 0x1) == 0)
which checks directly whether the bit is a 0 (i.e. the number is even)
We can check a number is even or odd without using modulus and division operator in c program The another method is using shift operators number >> 1) <<1==number then it is even number
Do not use if(( number >> 1) <<1==number) as it risks implementation defined behavior when number < 0.
Only for the pedantic
This is likely incorrect on rare machines that use ones' complement int encoding.
Of course such beast are so rare these days and the next version of C, C2x, is expected to no longer support non-2's complement encoding.
Alternative
Instead code can use:
is_odd = number & 1LLU;
This will convert various possible integer types of number into unsigned long long and then perform a simple mask of the least significant bit (the one's place). Even with negatives values in any encoding will convert mathematically to an unsigned value with the same even-ness.
Modulus operator??
... using modulus and division operator ...
In C there is no operator defined as modulus. There is %, which results in the remainder.
See What's the difference between “mod” and “remainder”?.
Right-shifting by one shifts off the low bit, left-shifting back restores the value without that low bit.
All odd numbers end in a low bit of 1, which this removes, so the equality comparison only returns true for even numbers, where the removal and re-adding of the low 0 bit does not change the value.

Can`t comprehend the bitwise operations

Reading the K&R book I stumbled upon chapter 2.9 which describes bitwise operators in C. Right in the beginning there is this claim:
The bitwise AND operator & is often used to mask off some set of bits, for example
n = n & 0177;
sets to zero all but the low-order 7 bits of n.
I am a bit confused with the true meaning of it. How does hexadecimal (if i got it right) 0177 represent low-order 7 bits? I tried to test it in code and below is what I did:
#include <stdio.h>
int main()
{
int n = 1490;
n = n & 0177;
printf("%i\n", n);
}
The output of the code is 82. Converting 1490 to binary I got 10111010010 and after setting all bits to zero apart from 7 low order bits i ended up with 1010010 which really equals 82 in decimal. Trying to understand the logic under the hood I applied &(AND) operator manually but it resulted in a completely different number. What I am doing wrong?
Please be aware that 0177 is not hexadecimal but the octal form of binary 01111111. Each octal digit represent 3 bits, and the leading 0 tells the compiler to interpret it that way.
So the operation is
decimal 1490 10111010010
octal 0177 00001111111
AND -----------
decimal 82 00001010010
The compiler interprets prefix 0 as base 8.
So 177(8) = 127(10) = 1111111(2).
That's your 7 bits right there.

left shifting unsigned int to 32 bits, generates warning [duplicate]

I recently picked up a copy of Applied Cryptography by Bruce Schneier and it's been a good read. I now understand how several algorithms outlined in the book work, and I'd like to start implementing a few of them in C.
One thing that many of the algorithms have in common is dividing an x-bit key, into several smaller y-bit keys. For example, Blowfish's key, X, is 64-bits, but you are required to break it up into two 32-bit halves; Xl and Xr.
This is where I'm getting stuck. I'm fairly decent with C, but I'm not the strongest when it comes to bitwise operators and the like.
After some help on IRC, I managed to come up with these two macros:
#define splitup(a, b, c) {b = a >> 32; c = a & 0xffffffff; }
#define combine(a, b, c) {a = (c << 32) | a;}
Where a is 64 bits and b and c are 32 bits. However, the compiler warns me about the fact that I'm shifting a 32 bit variable by 32 bits.
My questions are these:
What's bad about shifting a 32-bit variable 32 bits? I'm guessing it's undefined, but these macros do seem to be working.
Also, would you suggest I go about this another way?
As I said, I'm fairly familiar with C, but bitwise operators and the like still give me a headache.
EDIT
I figured out that my combine macro wasn't actually combining two 32-bit variables, but simply ORing 0 by a, and getting a as a result.
So, on top of my previous questions, I still don't have a method of combining the two 32-bit variables to get a 64-bit one; a suggestion on how to do it would be appreciated.
Yes, it is undefined behaviour.
ISO/IEC 9899:1999 6.5.7 Bitwise shift operators ¶3
The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. 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.
C11 aka ISO/IEC 9899:2011 says the same.
You should first cast b to the target integer type. Another point is that you should put parentheses around the macro parameters to avoid surprises by operator precedences. Additionally, the comma operator is very useful here, allowing you to avoid the braces, so that the macro can be used as a normal command, closed with a semicolon.
#define splitup(a,b,c) ( (b) = (a) >> 32, (c) = (a) & 0xffffffff )
#define combine(a,b,c) ( (a) = ((unsigned long long)(b) << 32) | (c) )
Additional casts may be necessary for `splitup to silence warnings about precision loss by over-paranoid compilers.
#define splitup(a,b,c) ( (b) = (unsigned long)((a) >> 32), (c) = (unsigned long)((a) & 0xffffffff) )
And please don't even think about using your self-written encryption for production code.
Shifting a 32-bit value by 32 bits or more is undefined in C and C++. One of the reasons it was left undefined is that on some hardware platforms the 32-bit shift instruction only takes into account 5 lowest bits of the supplied shift count. This means that whatever shift count you pass, it will be interpreted modulo 32. Attempting to shift by 32 on such platform will actually shift by 0, i.e. not shift at all.
The language authors did not want to burden the compilers written for such platform with the task of analyzing the shift count before doing the shift. Instead, the language specification says that the behavior is undefined. This means that if you want to get a 0 value from a 32-bit shift by 32 (or more), it is up to you to recognize the situation and process it accordingly.
what's bad about shifting a 32-bit variable 32 bits?
Its better to assign 0 to n-bit integer than to shift it by n-bits.
Example:
0 0 1 0 1 ----- 5 bit Integer
0 1 0 1 0 ----- 1st shift
1 0 1 0 0 ----- 2nd shift
0 1 0 0 0 ----- 3rd shift
1 0 0 0 0 ----- 4th shift
0 0 0 0 0 ----- 5th shift (all the bits are shifted!)
I still don't have a method of combining the two 32-bit variables to get a 64-bit one
Consider: a is 64 bit, b and c are 32 bit
a = b;
a = a << 32; //Note: a is 64 bit
a = a | c;
Unless this is some "reinventing the wheel to understand how it works" project, don't implement your own crypto functions.
Ever.
It's hard enough to use the available algorithms to work (and to choose the right one), don't shoot yourself in the foot by putting in production some home grown cryptor API. Chances are your encryption won't encrypt
What's bad about shifting a 32-bit variable 32 bits?
In addition to what have been already said, the 32nd bit is the sign bit, and you may get sign extension to preserve the sing, thereby losing significant bits.

Multiplication of two 32 bit numbers using only 8 bit numbers

I saw this interview question online and can't find a good method other than the usual additive methods.
Any suggestions if this can be done quicker using some bitshift / recursion or something similar ?
Bitshifting would be natural part of a solution.
To multiply a value a by an eight-bit value b, for each 1 bit in b, add up all the values of a multiplied by b with all other bits set to 0. For example, a * 10100001 = a * 10000000 + a * 00100000 + a * 00000001.
Taking this further, suppose we want to multiply 11001011 by 0010000, this is 11001011(bin) << 4(dec). Doing this on an eight-bit value gives you 10110000. You have also lost (8-4)=4 bits from the beginning. Hence you would also want to do 11001011(bin) >> 4(dec) to get 00001100 as a carry into the next "8-bit column" (assuming that we are using 8 columns to represent a 64-bit answer).
Recursion would not really be necessary. All you'd need is a loop through the 4 bytes of the first 32-bit number, with another loop through the 4 bytes of the second number inside, multiplying each pair of bytes together in turn and adding it to your solution.

What's bad about shifting a 32-bit variable 32 bits?

I recently picked up a copy of Applied Cryptography by Bruce Schneier and it's been a good read. I now understand how several algorithms outlined in the book work, and I'd like to start implementing a few of them in C.
One thing that many of the algorithms have in common is dividing an x-bit key, into several smaller y-bit keys. For example, Blowfish's key, X, is 64-bits, but you are required to break it up into two 32-bit halves; Xl and Xr.
This is where I'm getting stuck. I'm fairly decent with C, but I'm not the strongest when it comes to bitwise operators and the like.
After some help on IRC, I managed to come up with these two macros:
#define splitup(a, b, c) {b = a >> 32; c = a & 0xffffffff; }
#define combine(a, b, c) {a = (c << 32) | a;}
Where a is 64 bits and b and c are 32 bits. However, the compiler warns me about the fact that I'm shifting a 32 bit variable by 32 bits.
My questions are these:
What's bad about shifting a 32-bit variable 32 bits? I'm guessing it's undefined, but these macros do seem to be working.
Also, would you suggest I go about this another way?
As I said, I'm fairly familiar with C, but bitwise operators and the like still give me a headache.
EDIT
I figured out that my combine macro wasn't actually combining two 32-bit variables, but simply ORing 0 by a, and getting a as a result.
So, on top of my previous questions, I still don't have a method of combining the two 32-bit variables to get a 64-bit one; a suggestion on how to do it would be appreciated.
Yes, it is undefined behaviour.
ISO/IEC 9899:1999 6.5.7 Bitwise shift operators ¶3
The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. 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.
C11 aka ISO/IEC 9899:2011 says the same.
You should first cast b to the target integer type. Another point is that you should put parentheses around the macro parameters to avoid surprises by operator precedences. Additionally, the comma operator is very useful here, allowing you to avoid the braces, so that the macro can be used as a normal command, closed with a semicolon.
#define splitup(a,b,c) ( (b) = (a) >> 32, (c) = (a) & 0xffffffff )
#define combine(a,b,c) ( (a) = ((unsigned long long)(b) << 32) | (c) )
Additional casts may be necessary for `splitup to silence warnings about precision loss by over-paranoid compilers.
#define splitup(a,b,c) ( (b) = (unsigned long)((a) >> 32), (c) = (unsigned long)((a) & 0xffffffff) )
And please don't even think about using your self-written encryption for production code.
Shifting a 32-bit value by 32 bits or more is undefined in C and C++. One of the reasons it was left undefined is that on some hardware platforms the 32-bit shift instruction only takes into account 5 lowest bits of the supplied shift count. This means that whatever shift count you pass, it will be interpreted modulo 32. Attempting to shift by 32 on such platform will actually shift by 0, i.e. not shift at all.
The language authors did not want to burden the compilers written for such platform with the task of analyzing the shift count before doing the shift. Instead, the language specification says that the behavior is undefined. This means that if you want to get a 0 value from a 32-bit shift by 32 (or more), it is up to you to recognize the situation and process it accordingly.
what's bad about shifting a 32-bit variable 32 bits?
Its better to assign 0 to n-bit integer than to shift it by n-bits.
Example:
0 0 1 0 1 ----- 5 bit Integer
0 1 0 1 0 ----- 1st shift
1 0 1 0 0 ----- 2nd shift
0 1 0 0 0 ----- 3rd shift
1 0 0 0 0 ----- 4th shift
0 0 0 0 0 ----- 5th shift (all the bits are shifted!)
I still don't have a method of combining the two 32-bit variables to get a 64-bit one
Consider: a is 64 bit, b and c are 32 bit
a = b;
a = a << 32; //Note: a is 64 bit
a = a | c;
Unless this is some "reinventing the wheel to understand how it works" project, don't implement your own crypto functions.
Ever.
It's hard enough to use the available algorithms to work (and to choose the right one), don't shoot yourself in the foot by putting in production some home grown cryptor API. Chances are your encryption won't encrypt
What's bad about shifting a 32-bit variable 32 bits?
In addition to what have been already said, the 32nd bit is the sign bit, and you may get sign extension to preserve the sing, thereby losing significant bits.

Resources