ayush gupta
ayush gupta

Reputation: 627

Type casting and Bit Manipulation Mystery

#include <stdio.h>
#include <stdint.h>
typedef unsigned char       uint8_t;
typedef short               int16_t;
typedef unsigned short      uint16_t;
typedef int                 int32_t;
typedef unsigned int        uint32_t;
int main(){
    uint8_t ball; 
    uint8_t fool;
    ball=((unsigned char)13);
    fool=((unsigned char)14);
    uint16_t combined_value1=((uint16_t)ball)<<12+((uint16_t)fool)<<8; // WRONG ONE
    uint16_t combined_value2=((uint16_t)ball<<12)+((uint16_t)fool<<8);
    printf("%hu\n",(uint16_t)combined_value1);
    printf("%hu\n",(uint16_t)combined_value2);
    return 0;
}

Why is the value of "combined_value1" wrong? Here ball and fool take value from 0 to 15 and I am trying to concatenate combined_value as { ball[4 bits] : fool[4 bits] : [8 zero bits] }.

Upvotes: 2

Views: 106

Answers (1)

AlexD
AlexD

Reputation: 32576

+ has higher precedence than <<, so

((uint16_t)ball)<<12+((uint16_t)fool)<<8;

is evaluated as

((uint16_t)ball) << (12+((uint16_t)fool)) << 8;

Please note that (uint16_t) casting does not make much sense in this context, since after that promotion to int takes place. Instead, consider

uint16_t combined_value = (uint16_t)((ball<<12) + (fool<<8));

There are several other redundant castings too. And as @StoryTeller suggested, it would be better to include stdint.h.

Upvotes: 5

Related Questions