简体   繁体   English

通过右移>>和左移<<按位运算进行日期编码

[英]Date encoding through Righ Shift >> and Left Shift << bitwise operation

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.我正在尝试解决 C 编程问题,这是使用位移操作和解码回日期、月份和年份的 2 个字节的日期编码。 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.问题是:即使一切似乎都正确,日期和月份的 output 对双位移位操作没有影响。 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.我使用了unsigned char所以最后一个符号位绝对不是问题。 The Showbits function is just to show the bits. Showbits function 只是为了展示这些位。 I am using gcc g++ compiler with VSCode in Windows 10.我在 Windows 10 中使用带有 VSCode 的 gcc g++ 编译器。

//  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;
}

I change the data type suitable for 16-bit as suggested by Fe2O3 and it works as expected.我按照 Fe2O3 的建议更改了适合 16 位的数据类型,它按预期工作。

#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;
}

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
*/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM