Unexpected result after chaining bit-shift operators in C - c

I can't figure out why chaining bit-shift operations is not returning the same result as not chaining them.
#include <stdio.h>
void bit_manip_func(unsigned char byte)
{
unsigned char chain = (((byte >> 3) << 7) >> 3);
printf("%d\n", chain); //this prints 144
unsigned char o1 = byte >> 3;
unsigned char o2 = o1 << 7;
unsigned char o3 = o2 >> 3;
printf("%d\n", o3); //this prints 16 as expected
}
int main()
{
//expecting both printf's to print
//the same value (16).
bit_manip_func(73);
return 0;
}
I'm expecting both printf calls to print out 16 since 73 in binary is 0100 1001. After applying byte >> 3 I should get 0000 1001, after (byte >> 3) << 7 the result should be 1000 0000, and after (((byte >> 3) << 7) >> 3) the result should be 0001 0000, which of course is 16. What's actually happening?

The operators >> and << perform integer promotions on their operands. Thus the type unsigned char is promoted to int, when used with either operator.
In the following line, the variable byte is promoted to type int, and then all three operations are performed on this type:
unsigned char chain = (((byte >> 3) << 7) >> 3);
The left most bit set to one is thus preserved:
01001001 => 01001 => 010010000000 => 010010000
^ ^ ^ ^
In the following code, the variables are promoted to type int, but after each operation, the result, which has the type int, is assigned to an unsigned char and thus wraps (most significant bits are removed),
since the range of unsigned char is [ 0 , 2^8-1 ] on your platform.
unsigned char o1 = byte >> 3;
unsigned char o2 = o1 << 7;
unsigned char o3 = o2 >> 3;
This means that the left most bit set to one is not preserved:
01001001 => 01001 => 10000000 => 000010000
^ ^

In
unsigned char chain = (((byte >> 3) << 7) >> 3);
((byte >> 3) << 7) is promoted to an int, then it performs >> 3 over the int
Wrapped to an unsigned char (mod 256) you get ((73 >> 3) << 7) >> 3) % 256 = 144
Use a cast:
unsigned char chain = ((unsigned char)((byte >> 3) << 7) >> 3);

Related

Is there a way of using bitwise operator to combine digit bits?

For example, I have two digit bits:
0b0111111
0b0000110
I want to shift a state variable by 7 digits and combine them together.
0b00001100111111
Can I accomplish by shifting?
You do this by shifting the bottom number left 7 digits, then performing a bitwise OR of the result and the first number.
unsigned int a = 0x3f;
unsigned int b = 0x06;
unsigned int result = (b << 7) | a;
unsigned int X = 0b00111111;
unsigned int Y = 0b00000110;
unsigned int Z = ((X << 7) & 0xFF00) | Y;
unsigned char a = 0b00000110;
unsigned char b = 0b01111111;
unsigned short c = (b << 8); // shift everything left 8 bits to set the high bits
c &= 0xFF00; // clear out the lower bits - not necessary in C
c |= a; // set the lower 8 bits
int a = 0b0111111;
int b = 0b0000110;
int combined = (a << 7) | b;

Can someone explain how this bitMask code works?

This is code that my partner came up with but for some reason I can't get a hold of him to ask him how it's suppose to work. I've been through it many times now and can't seem to get the answer I'm suppose to get.
/**
* bitMask - Generate a mask consisting of all 1's
* lowbit and highbit
* Examples: bitMask(5,3) = 0x38
* Assume 0 <= lowbit <= 31, and 0 <= highbit <= 31
* If lowbit > highbit, then mask should be all 0's
* Legal ops: ! ~ & ^ | + << >>
*/
int bitMask(int highbit, int lowbit) {
int i = ~0;
return ~(i << highbit << 1) & (i << lowbit);
}
This function is actually incorrect: for large values of highbit and lowbit, it may have implementation specific behavior or even undefined behavior. It should use and return unsigned types:
unsigned bitMask(int highbit, int lowbit) {
unsigned i = ~0U;
return ~(i << highbit << 1) & (i << lowbit);
}
Here are the steps:
i = ~0U; sets i to all bits 1.
i << highbit shifts these bits to the left, inserting highbit 0 bits in the low order bits.
i << highbit << 1 makes room for one more 0 bit. One should not simplify this expression as i << (highbit + 1) because such a bit shift is implementation defined if highbit + 1 becomes larger or equal to the number of bits in the type of i.
~(i << highbit << 1) complements this mask, creating a mask with highbit + 1 bits set in the low order positions and 0 for the higher bits.
i << lowbit creates a mask with lowbit 0 bits and 1 in the higher positions.
~(i << highbit << 1) & (i << lowbit) computes the intersection of these 2 masks, result has 1 bits from bit number lowbit to bit number highbit inclusive, numbering the bits from 0 for the least significant.
examples:
bitMask(31, 0) -> 0xFFFFFFFF.
bitMask(0, 0) -> 0x00000001.
bitMask(31, 16) -> 0xFFFF0000.
bitMask(15, 0) -> 0x0000FFFF.
This numbering method is used in hardware specifications. I personally prefer a different method where one specifies the number of bits to skip and the number of bits to set, more consistent with bit-field specifications:
unsigned bitSpec(int start, int len) {
return (~0U >> (32 - len)) << start;
}
and the same examples:
bitSpec(0, 32) -> 0xFFFFFFFF.
bitSpec(0, 1) -> 0x00000001.
bitSpec(16, 16) -> 0xFFFF0000.
bitSpec(0, 16) -> 0x0000FFFF.
In your case, given the description included with your function, the function is doing exactly what you seem to intend it to do. The primary problem is you are using int instead of unsigned int. That will cause problems with sign extension. (not to mention the lack of definition for signed shifts in C).
A simple conversion to unsigned will show you it is operating as you expect:
Short example:
#include <stdio.h>
#include <stdlib.h>
unsigned int bitMask (unsigned int highbit, unsigned int lowbit) {
unsigned int i = ~0;
return ~(i << highbit << 1) & (i << lowbit);
}
char *binstr (unsigned long n, unsigned char sz, unsigned char szs, char sep) {
static char s[128 + 1] = {0};
char *p = s + 128;
unsigned char i;
for (i = 0; i < sz; i++) {
p--;
if (i > 0 && szs > 0 && i % szs == 0)
*p-- = sep;
*p = (n >> i & 1) ? '1' : '0';
}
return p;
}
int main (int argc, char **argv) {
unsigned high = argc > 1 ? (unsigned)strtoul (argv[1], NULL, 10) : 5;
unsigned low = argc > 2 ? (unsigned)strtoul (argv[2], NULL, 10) : 3;
printf ("%s\n", binstr (bitMask (high, low), 32, 8, '-'));
return 0;
}
Output
$ ./bin/bitmask
00000000-00000000-00000000-00111000
$ ./bin/bitmask 10 3
00000000-00000000-00000111-11111000
$ ./bin/bitmask 31 5
11111111-11111111-11111111-11100000
$ ./bin/bitmask 4 8
00000000-00000000-00000000-00000000

Convert Little Endian to Big Endian

I just want to ask if my method is correct to convert from little endian to big endian, just to make sure if I understand the difference.
I have a number which is stored in little-endian, here are the binary and hex representations of the number:
‭0001 0010 0011 0100 0101 0110 0111 1000‬
‭12345678‬
In big-endian format I believe the bytes should be swapped, like this:
1000 0111 0110 0101 0100 0011 0010 0001
‭87654321
Is this correct?
Also, the code below attempts to do this but fails. Is there anything obviously wrong or can I optimize something? If the code is bad for this conversion can you please explain why and show a better method of performing the same conversion?
uint32_t num = 0x12345678;
uint32_t b0,b1,b2,b3,b4,b5,b6,b7;
uint32_t res = 0;
b0 = (num & 0xf) << 28;
b1 = (num & 0xf0) << 24;
b2 = (num & 0xf00) << 20;
b3 = (num & 0xf000) << 16;
b4 = (num & 0xf0000) << 12;
b5 = (num & 0xf00000) << 8;
b6 = (num & 0xf000000) << 4;
b7 = (num & 0xf0000000) << 4;
res = b0 + b1 + b2 + b3 + b4 + b5 + b6 + b7;
printf("%d\n", res);
OP's sample code is incorrect.
Endian conversion works at the bit and 8-bit byte level. Most endian issues deal with the byte level. OP's code is doing a endian change at the 4-bit nibble level. Recommend instead:
// Swap endian (big to little) or (little to big)
uint32_t num = 9;
uint32_t b0,b1,b2,b3;
uint32_t res;
b0 = (num & 0x000000ff) << 24u;
b1 = (num & 0x0000ff00) << 8u;
b2 = (num & 0x00ff0000) >> 8u;
b3 = (num & 0xff000000) >> 24u;
res = b0 | b1 | b2 | b3;
printf("%" PRIX32 "\n", res);
If performance is truly important, the particular processor would need to be known. Otherwise, leave it to the compiler.
[Edit] OP added a comment that changes things.
"32bit numerical value represented by the hexadecimal representation (st uv wx yz) shall be recorded in a four-byte field as (st uv wx yz)."
It appears in this case, the endian of the 32-bit number is unknown and the result needs to be store in memory in little endian order.
uint32_t num = 9;
uint8_t b[4];
b[0] = (uint8_t) (num >> 0u);
b[1] = (uint8_t) (num >> 8u);
b[2] = (uint8_t) (num >> 16u);
b[3] = (uint8_t) (num >> 24u);
[2016 Edit] Simplification
... The type of the result is that of the promoted left operand.... Bitwise shift operators C11 §6.5.7 3
Using a u after the shift constants (right operands) results in the same as without it.
b3 = (num & 0xff000000) >> 24u;
b[3] = (uint8_t) (num >> 24u);
// same as
b3 = (num & 0xff000000) >> 24;
b[3] = (uint8_t) (num >> 24);
Sorry, my answer is a bit too late, but it seems nobody mentioned built-in functions to reverse byte order, which in very important in terms of performance.
Most of the modern processors are little-endian, while all network protocols are big-endian. That is history and more on that you can find on Wikipedia. But that means our processors convert between little- and big-endian millions of times while we browse the Internet.
That is why most architectures have a dedicated processor instructions to facilitate this task. For x86 architectures there is BSWAP instruction, and for ARMs there is REV. This is the most efficient way to reverse byte order.
To avoid assembly in our C code, we can use built-ins instead. For GCC there is __builtin_bswap32() function and for Visual C++ there is _byteswap_ulong(). Those function will generate just one processor instruction on most architectures.
Here is an example:
#include <stdio.h>
#include <inttypes.h>
int main()
{
uint32_t le = 0x12345678;
uint32_t be = __builtin_bswap32(le);
printf("Little-endian: 0x%" PRIx32 "\n", le);
printf("Big-endian: 0x%" PRIx32 "\n", be);
return 0;
}
Here is the output it produces:
Little-endian: 0x12345678
Big-endian: 0x78563412
And here is the disassembly (without optimization, i.e. -O0):
uint32_t be = __builtin_bswap32(le);
0x0000000000400535 <+15>: mov -0x8(%rbp),%eax
0x0000000000400538 <+18>: bswap %eax
0x000000000040053a <+20>: mov %eax,-0x4(%rbp)
There is just one BSWAP instruction indeed.
So, if we do care about the performance, we should use those built-in functions instead of any other method of byte reversing. Just my 2 cents.
I think you can use function htonl(). Network byte order is big endian.
"I swap each bytes right?" -> yes, to convert between little and big endian, you just give the bytes the opposite order.
But at first realize few things:
size of uint32_t is 32bits, which is 4 bytes, which is 8 HEX digits
mask 0xf retrieves the 4 least significant bits, to retrieve 8 bits, you need 0xff
so in case you want to swap the order of 4 bytes with that kind of masks, you could:
uint32_t res = 0;
b0 = (num & 0xff) << 24; ; least significant to most significant
b1 = (num & 0xff00) << 8; ; 2nd least sig. to 2nd most sig.
b2 = (num & 0xff0000) >> 8; ; 2nd most sig. to 2nd least sig.
b3 = (num & 0xff000000) >> 24; ; most sig. to least sig.
res = b0 | b1 | b2 | b3 ;
You could do this:
int x = 0x12345678;
x = ( x >> 24 ) | (( x << 8) & 0x00ff0000 )| ((x >> 8) & 0x0000ff00) | ( x << 24) ;
printf("value = %x", x); // x will be printed as 0x78563412
One slightly different way of tackling this that can sometimes be useful is to have a union of the sixteen or thirty-two bit value and an array of chars. I've just been doing this when getting serial messages that come in with big endian order, yet am working on a little endian micro.
union MessageLengthUnion
{
uint16_t asInt;
uint8_t asChars[2];
};
Then when I get the messages in I put the first received uint8 in .asChars[1], the second in .asChars[0] then I access it as the .asInt part of the union in the rest of my program.
If you have a thirty-two bit value to store you can have the array four long.
I am assuming you are on linux
Include "byteswap.h" & Use int32_t bswap_32(int32_t argument);
It is logical view, In actual see, /usr/include/byteswap.h
one more suggestion :
unsigned int a = 0xABCDEF23;
a = ((a&(0x0000FFFF)) << 16) | ((a&(0xFFFF0000)) >> 16);
a = ((a&(0x00FF00FF)) << 8) | ((a&(0xFF00FF00)) >>8);
printf("%0x\n",a);
A Simple C program to convert from little to big
#include <stdio.h>
int main() {
unsigned int little=0x1234ABCD,big=0;
unsigned char tmp=0,l;
printf(" Little endian little=%x\n",little);
for(l=0;l < 4;l++)
{
tmp=0;
tmp = little | tmp;
big = tmp | (big << 8);
little = little >> 8;
}
printf(" Big endian big=%x\n",big);
return 0;
}
OP's code is incorrect for the following reasons:
The swaps are being performed on a nibble (4-bit) boundary, instead of a byte (8-bit) boundary.
The shift-left << operations of the final four swaps are incorrect, they should be shift-right >> operations and their shift values would also need to be corrected.
The use of intermediary storage is unnecessary, and the code can therefore be rewritten to be more concise/recognizable. In doing so, some compilers will be able to better-optimize the code by recognizing the oft-used pattern.
Consider the following code, which efficiently converts an unsigned value:
// Swap endian (big to little) or (little to big)
uint32_t num = 0x12345678;
uint32_t res =
((num & 0x000000FF) << 24) |
((num & 0x0000FF00) << 8) |
((num & 0x00FF0000) >> 8) |
((num & 0xFF000000) >> 24);
printf("%0x\n", res);
The result is represented here in both binary and hex, notice how the bytes have swapped:
‭0111 1000 0101 0110 0011 0100 0001 0010‬
78563412
Optimizing
In terms of performance, leave it to the compiler to optimize your code when possible. You should avoid unnecessary data structures like arrays for simple algorithms like this, doing so will usually cause different instruction behavior such as accessing RAM instead of using CPU registers.
#include <stdio.h>
#include <inttypes.h>
uint32_t le_to_be(uint32_t num) {
uint8_t b[4] = {0};
*(uint32_t*)b = num;
uint8_t tmp = 0;
tmp = b[0];
b[0] = b[3];
b[3] = tmp;
tmp = b[1];
b[1] = b[2];
b[2] = tmp;
return *(uint32_t*)b;
}
int main()
{
printf("big endian value is %x\n", le_to_be(0xabcdef98));
return 0;
}
You can use the lib functions. They boil down to assembly, but if you are open to alternate implementations in C, here they are (assuming int is 32-bits) :
void byte_swap16(unsigned short int *pVal16) {
//#define method_one 1
// #define method_two 1
#define method_three 1
#ifdef method_one
unsigned char *pByte;
pByte = (unsigned char *) pVal16;
*pVal16 = (pByte[0] << 8) | pByte[1];
#endif
#ifdef method_two
unsigned char *pByte0;
unsigned char *pByte1;
pByte0 = (unsigned char *) pVal16;
pByte1 = pByte0 + 1;
*pByte0 = *pByte0 ^ *pByte1;
*pByte1 = *pByte0 ^ *pByte1;
*pByte0 = *pByte0 ^ *pByte1;
#endif
#ifdef method_three
unsigned char *pByte;
pByte = (unsigned char *) pVal16;
pByte[0] = pByte[0] ^ pByte[1];
pByte[1] = pByte[0] ^ pByte[1];
pByte[0] = pByte[0] ^ pByte[1];
#endif
}
void byte_swap32(unsigned int *pVal32) {
#ifdef method_one
unsigned char *pByte;
// 0x1234 5678 --> 0x7856 3412
pByte = (unsigned char *) pVal32;
*pVal32 = ( pByte[0] << 24 ) | (pByte[1] << 16) | (pByte[2] << 8) | ( pByte[3] );
#endif
#if defined(method_two) || defined (method_three)
unsigned char *pByte;
pByte = (unsigned char *) pVal32;
// move lsb to msb
pByte[0] = pByte[0] ^ pByte[3];
pByte[3] = pByte[0] ^ pByte[3];
pByte[0] = pByte[0] ^ pByte[3];
// move lsb to msb
pByte[1] = pByte[1] ^ pByte[2];
pByte[2] = pByte[1] ^ pByte[2];
pByte[1] = pByte[1] ^ pByte[2];
#endif
}
And the usage is performed like so:
unsigned short int u16Val = 0x1234;
byte_swap16(&u16Val);
unsigned int u32Val = 0x12345678;
byte_swap32(&u32Val);
Below is an other approach that was useful for me
convertLittleEndianByteArrayToBigEndianByteArray (byte littlendianByte[], byte bigEndianByte[], int ArraySize){
int i =0;
for(i =0;i<ArraySize;i++){
bigEndianByte[i] = (littlendianByte[ArraySize-i-1] << 7 & 0x80) | (littlendianByte[ArraySize-i-1] << 5 & 0x40) |
(littlendianByte[ArraySize-i-1] << 3 & 0x20) | (littlendianByte[ArraySize-i-1] << 1 & 0x10) |
(littlendianByte[ArraySize-i-1] >>1 & 0x08) | (littlendianByte[ArraySize-i-1] >> 3 & 0x04) |
(littlendianByte[ArraySize-i-1] >>5 & 0x02) | (littlendianByte[ArraySize-i-1] >> 7 & 0x01) ;
}
}
Below program produce the result as needed:
#include <stdio.h>
unsigned int Little_To_Big_Endian(unsigned int num);
int main( )
{
int num = 0x11223344 ;
printf("\n Little_Endian = 0x%X\n",num);
printf("\n Big_Endian = 0x%X\n",Little_To_Big_Endian(num));
}
unsigned int Little_To_Big_Endian(unsigned int num)
{
return (((num >> 24) & 0x000000ff) | ((num >> 8) & 0x0000ff00) | ((num << 8) & 0x00ff0000) | ((num << 24) & 0xff000000));
}
And also below function can be used:
unsigned int Little_To_Big_Endian(unsigned int num)
{
return (((num & 0x000000ff) << 24) | ((num & 0x0000ff00) << 8 ) | ((num & 0x00ff0000) >> 8) | ((num & 0xff000000) >> 24 ));
}
#include<stdio.h>
int main(){
int var = 0X12345678;
var = ((0X000000FF & var)<<24)|
((0X0000FF00 & var)<<8) |
((0X00FF0000 & var)>>8) |
((0XFF000000 & var)>>24);
printf("%x",var);
}
Here is a little function I wrote that works pretty good, its probably not portable to every single machine or as fast a single cpu instruction, but should work for most. It can handle numbers up to 32 byte (256 bit) and works for both big and little endian swaps. The nicest part about this function is you can point it into a byte array coming off or going on the wire and swap the bytes inline before converting.
#include <stdio.h>
#include <string.h>
void byteSwap(char**,int);
int main() {
//32 bit
int test32 = 0x12345678;
printf("\n BigEndian = 0x%X\n",test32);
char* pTest32 = (char*) &test32;
//convert to little endian
byteSwap((char**)&pTest32, 4);
printf("\n LittleEndian = 0x%X\n", test32);
//64 bit
long int test64 = 0x1234567891234567LL;
printf("\n BigEndian = 0x%lx\n",test64);
char* pTest64 = (char*) &test64;
//convert to little endian
byteSwap((char**)&pTest64,8);
printf("\n LittleEndian = 0x%lx\n",test64);
//back to big endian
byteSwap((char**)&pTest64,8);
printf("\n BigEndian = 0x%lx\n",test64);
return 0;
}
void byteSwap(char** src,int size) {
int x = 0;
char b[32];
while(size-- >= 0) { b[x++] = (*src)[size]; };
memcpy(*src,&b,x);
}
output:
$gcc -o main *.c -lm
$main
BigEndian = 0x12345678
LittleEndian = 0x78563412
BigEndian = 0x1234567891234567
LittleEndian = 0x6745239178563412
BigEndian = 0x1234567891234567

Swap byte 2 and 4 in a 32 bit integer

I had this interview question -
Swap byte 2 and byte 4 within an integer sequence.
Integer is a 4 byte wide i.e. 32 bits
My approach was to use char *pointer and a temp char to swap the bytes.
For clarity I have broken the steps otherwise an character array can be considered.
unsigned char *b2, *b4, tmpc;
int n = 0xABCD; ///expected output 0xADCB
b2 = &n; b2++;
b4 = &n; b4 +=3;
///swap the values;
tmpc = *b2;
*b2 = *b4;
*b4 = tmpc;
Any other methods?
int someInt = 0x12345678;
int byte2 = someInt & 0x00FF0000;
int byte4 = someInt & 0x000000FF;
int newInt = (someInt & 0xFF00FF00) | (byte2 >> 16) | (byte4 << 16);
To avoid any concerns about sign extension:
int someInt = 0x12345678;
int newInt = (someInt & 0xFF00FF00) | ((someInt >> 16) & 0x000000FF) | ((someInt << 16) & 0x00FF0000);
(Or, to really impress them, you could use the triple XOR technique.)
Just for fun (probably a tupo somewhere):
int newInt = someInt ^ ((someInt >> 16) & 0x000000FF);
newInt = newInt ^ ((newInt << 16) & 0x00FF0000);
newInt = newInt ^ ((newInt >> 16) & 0x000000FF);
(Actually, I just tested it and it works!)
You can mask out the bytes you want and shift them around. Something like this:
unsigned int swap(unsigned int n) {
unsigned int b2 = (0x0000FF00 & n);
unsigned int b4 = (0xFF000000 & n);
n ^= b2 | b4; // Clear the second and fourth bytes
n |= (b2 << 16) | (b4 >> 16); // Swap and write them.
return n;
}
This assumes that the "first" byte is the lowest order byte (even if in memory it may be stored big-endian).
Also it uses unsigned ints everywhere to avoid right shifting introducing extra 1s due to sign extension.
What about unions?
int main(void)
{
char tmp;
union {int n; char ary[4]; } un;
un.n = 0xABCDEF00;
tmp = un.ary[3];
un.ary[3] = un.ary[1];
un.ary[1] = tmp;
printf("0x%.2X\n", un.n);
}
in > 0xABCDEF00
out>0xEFCDAB00
Please don't forget to check endianess. this only work for little endian, but should not be hard to make it portable.

replace byte in 32 bit number

I have a function called replaceByte(x,n,c) that is to replace byte n in x with c with the following restrictions:
Bytes numbered from 0 (LSB) to 3 (MSB)
Examples: replaceByte(0x12345678,1,0xab) = 0x1234ab78
You can assume 0 <= n <= 3 and 0 <= c <= 255
Legal ops: ! ~ & ^ | + << >>
Max ops: 10
int replaceByte(int x, int n, int c) {
int shift = (c << (8 * n));
int mask = 0xff << shift;
return (mask & x) | shift;
}
but when I test it I get this error:
ERROR: Test replaceByte(-2147483648[0x80000000],0[0x0],0[0x0]) failed...
...Gives 0[0x0]. Should be -2147483648[0x80000000]
after realizing that * is not a legal operator I have finally figured it out...and if you are curious, this is what I did:
int replaceByte(int x, int n, int c) {
int mask = 0xff << (n << 3);
int shift = (c << (n << 3));
return (~mask & x) | shift;
}
Since this looks like homework I'm not going to post code, but list the steps you need to perform:
Cast c into a 32-bit number so you don't lose any bits while shifting
Next, shift c by the appropriate number of bits to the left (if n==0 no shifting, if n==1 shift by 8 etc.)
Create a 32-bit bitmask that will zero the lowest 8 bits of x, then shift this mask by the same amount as the last step
Perform bitwise AND of the shifted bitmask and x to zero out the appropriate bits of x
Perform bitwise OR (or addition) of the shifted c value and x to replace the masked bits of the latter
Ahh... You are almost there.
Just change
return (mask & x) | shift;
to
return (~mask & x) | shift;
The mask should contain all ones except for the region to be masked and not vice versa.
I am using this simple code and it works fine in gcc
#include<stdio.h>
int replaceByte(int x, int n, int c)
{
int shift = (c << (8 * n));
int mask = 0xff << shift;
return (~mask & x) | shift;
}
int main ()
{
printf("%X",replaceByte(0x80000000,0,0));
return 0;
}
Proper solution is for c = 0 as well:
int replaceByte(int x, int n, int c)
{
int shift = 8 * n;
int value = c << shift;
int mask = 0xff << shift;
return (~mask & x) | value;
}

Resources