Home > Software design >  Date encoding through Righ Shift >> and Left Shift << bitwise operation
Date encoding through Righ Shift >> and Left Shift << bitwise operation

Time:09-17

I am trying to solve a C programming problem, which is date encoding in 2 bytes using bit shifting operations and decoding back to date, month and year. While I could also use bitwise & and | operation, I want to use just bit shifting.

The issue is: even though everything seems to be right the output of date and month has no effect of dual bit shifting operation. The year is okay because there is only one operation. Meaning that the dual operation of bit shift is somehow not behaving as required.

I have used unsigned char so last sign bit is definitely not the issue. The Showbits function is just to show the bits. I am using gcc g compiler with VSCode in Windows 10.

//  Date encoding in 2-byte number

#include <stdio.h>
#include <conio.h>

typedef unsigned int uint;

Showbits(int n)
{
    int i, k, mask;

    for (i = 15; i >= 0; i--)
    {
        mask = 1 << i;
        k = n & mask;
        k == 0 ? printf("0") : printf("1");
    }
}

int main()
{

    uint encd_date, date, month, year;

    year = 2022;
    month = 9;
    date = 15;
    encd_date = 512 * (year - 1980)   32 * month   date;

    printf("\nEncoded date:%u\n", encd_date);
    printf("\nencd_date: ");
    Showbits(encd_date);

    year = (1980   (encd_date >> 9));
    month = (encd_date << 7);
    month = (month >> 12);
    date = (encd_date << 11);
    date = (date >> 11);

    printf("\ndate: ");
    Showbits(date);

    printf("\nmonth: ");
    Showbits(month);

    printf("\nyear: ");
    Showbits(year);

    printf("\nDecoded date %u month %u year %u", date, month, year);

    return 0;
}

CodePudding user response:

I change the data type suitable for 16-bit as suggested by Fe2O3 and it works as expected.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

typedef uint16_t uint;

void Showbits(int n)
{
    int i, k, mask;

    for (i = 15; i >= 0; i--)
    {
        mask = 1 << i;
        k = n & mask;
        k == 0 ? printf("0") : printf("1");
    }
}

int main()
{

    uint encd_date, date, month, year;

    year = 2022;
    month = 9;
    date = 15;
    encd_date = 512 * (year - 1980)   32 * month   date;

    printf("\nEncoded date:%u\n", encd_date);
    printf("\nencd_date: ");
    Showbits(encd_date);

    year = (1980   (encd_date >> 9));
    month = (encd_date << 7);
    month = (month >> 12);
    date = (encd_date << 11);
    date = (date >> 11);

    printf("\ndate: ");
    Showbits(date);

    printf("\nmonth: ");
    Showbits(month);

    printf("\nyear: ");
    Showbits(year);

    printf("\nDecoded date %u month %u year %u", date, month, year);

    return 0;
}

CodePudding user response:

Please don't ask me to explain it. It's late here.

It's almost if the carry-out of the left shift is being dragged back in on the right shift operations... (or something...)

A bridging 'fix' is to use an intermediary variable that seems to "clear up" the problem. This seems to work(around) for whatever reason.

int main() {
    uint16_t y = 2022;
    uint16_t m = 9;
    uint16_t d = 15;
    uint16_t u;

    uint16_t encd_date = (y-1980)*512   m*32   d;

                            y = (encd_date >> 9)   1980;
    u = encd_date <<  7;    m = u >> (7 5);
    u = encd_date << 11;    d = u >> 11;

    printf( "\nDecoded year %d month %d date %d", y, m, d );

    return 0;
}

/* Output
Decoded year 2022 month 9 date 15
*/
  • Related