C ++中的二进制运算符,转换问题[关闭]

问题描述 投票:0回答:2

我设计了一个简单的数据报和数据包结构。我还尝试编写函数,该函数会将数据报转换为数据包,并将数据报转换为数据报。

但是,在测试时,我发现有问题。该代码应该两次显示数字134,而不仅仅是一次。也就是说,SessionIDd1d2中应该相同,但不相同。有什么想法吗?

#include <stdint.h>
#include <ctime>
#include <random>

//Packet
    //a = [00000000] 2 bits Operation, 6 bits of first number [00|000000]
    //b = [00000000] 8 bits of first number [00000000]
    //c = [00000000] 2 bits of fist number and six bits of second number [00|000000]
    //d = [00000000] 8 bits of second number [00000000]
    //e = [00000000] 2 bits of second number 3 bits of Status and 3 bits of 3 bits of SessionID[00|000|000]
    //f = [00000000] 5 bits of SessionID and 3 bits of answer [00000000]


struct Packet { //[00000000|00000000|00000000|00000000|00000000|00000000]
    uint8_t  a, b, c, d, e, f;
    Packet() {
        a = 0b00000000;
        b = 0b00000000;
        c = 0b00000000;
        d = 0b00000000;
        e = 0b00000000;
        f = 0b00000000;
    }
};

//Create our packet
struct Datagram { //[00|0000000000000000|0000000000000000|000|00000000|000]
    uint8_t  Operation, Status, SessionID, Answer;
    uint16_t  FirstNumber, SecondNumber;
    Datagram() {
        this->Operation = 0b00000000;
        this->FirstNumber = 0b0000000000000000;
        this->SecondNumber = 0b0000000000000000;
        this->Status = 0b00000000;
        this->SessionID = 0b00000000;
        this->Answer = 0b00000000;
    }
};

//Change Datagram to Packet
Datagram ChangeToDatagram(Packet p0) {
    Datagram result;

    result.Operation = p0.a & 0b11000000;
    result.Operation >>= 6;

    uint8_t  x1 = 0;
    x1 = p0.a & 0b00111111;
    uint8_t  y1 = 0;
    y1 = p0.b & 0b11111111;
    uint8_t  z1 = 0;
    z1 = p0.c & 0b11000000;
    result.FirstNumber = x1 | y1 | z1;
    result.FirstNumber <<= 2;

    uint8_t  x2 = 0;
    x2 = p0.c & 0b00111111;
    uint8_t  y2 = 0;
    y2 = p0.d & 0b11111111;
    uint8_t  z2 = 0;
    z2 = p0.e & 0b11000000;
    result.SecondNumber = x2 | y2 | z2;
    result.SecondNumber <<= 2;

    result.Status = p0.e & 0b00111000;
    result.Status >>= 3;

    uint8_t  x3 = 0;
    x3 = p0.e & 0b00000111;
    uint8_t  y3 = 0;
    y3 = p0.f & 0b11111000;
    result.SessionID = x3 | y3;
    result.SessionID >>= 3;

    result.Answer = p0.f & 0b00000111;

    return result;
}

//Change Packet to Datagram
Packet ChangeToPacket(Datagram d) {
    Packet result;

    result.a = d.Operation <<= 6;
    uint16_t  x1 = 0;
    x1 = d.FirstNumber & 0b1111111111111111;
    x1 >>= 10;
    x1 <<= 8; // <<=10

    result.a = result.a | x1;

    uint16_t  y1 = 0;
    y1 = d.FirstNumber & 0b1111111111111111;
    y1 <<= 6;
    y1 >>= 6;
    y1 >>= 2;
    y1 <<= 2;
    result.b = y1;

    uint16_t  z1 = 0;
    z1 = d.FirstNumber & 0b1111111111111111;
    z1 <<= 14;
    //z1 >>= 14;
    uint16_t  x2 = 0;
    x2 = d.SecondNumber & 0b1111111111111111;
    x2 >>= 10;
    x2 <<= 8; //<<= 10;
    result.c = z1 | x2;

    uint16_t  y2 = 0;
    y2 = d.SecondNumber & 0b1111111111111111;
    y2 <<= 6;
    y2 >>= 6;
    y2 >>= 2;
    y2 <<= 2;
    result.d = y2;

    uint16_t  z2 = 0;
    z2 = d.SecondNumber & 0b1111111111111111;
    z2 <<= 14;
    //z2 >>= 14;
    uint8_t  x3 = 0;
    x3 = d.Status <<= 3;
    uint8_t  x4 = 0;
    x4 = d.SessionID & 0b11111111;
    x4 >>= 5;
    result.e = z2 | x3 | x4 ;

    uint8_t  y4 = 0;
    y4 = d.SessionID & 0b11111111;
    y4 <<= 3;
    uint8_t  x5 = 0;
    x5 = d.Answer;
    result.f = y4 | x5;

    return result;
}

int main()
{
    Datagram d1,d2;
    Packet p1,p2;

    d1.SessionID = 134;
    p1 = ChangeToPacket(d1);
    d2 = ChangeToDatagram(p1);

    printf("%d %d\n", d1.SessionID, d2.SessionID);

    return 0;
}
c++ bitwise-operators
2个回答
0
投票

查看您如何重建SessionID值。您将丢弃从p0.e中提取的3位,这些3位属于SessionID值的高3位。

适当的重建是

result.SessionID =  (y3 >> 3) | (x3 << 5);

0
投票

很难阅读和调试此代码,我注意到了一些错误,如:

result.a = d.Operation <<= 6;

但更容易将其更改为:

//Change Packet to Datagram
Packet ChangeToPacket(Datagram d) {
    Packet result;

    result.a = ((d.Operation & 0b11) << 6) | ((d.FirstNumber >> 10) & 0b111111); // 2 bits of operation and 6 bits of first number
    result.b = (d.FirstNumber >> 2) & 0b11111111; // 8 bits of first number
    result.c = ((d.FirstNumber & 0b11) << 6) | ((d.SecondNumber >> 10) & 0b111111); // 2 bits of first number and 6 bits of second number
    result.d = (d.SecondNumber >> 2) & 0b11111111; // 8 bits of second number
    result.e = ((d.SecondNumber & 0b11) << 6) | ((d.Status & 0b111) << 3) | ((d.SessionID & 0b11111111) >> 5); // 2 bits of second number and 3 bits of status and 3 bits of session
    result.f = ((d.SessionID & 0b11111) << 3) | (d.Answer & 0b111); // 5 bits of session and 3 bits of answer

    return result;
}

//Change Datagram to Packet
Datagram ChangeToDatagram(Packet p0) {
    Datagram result;

    result.Operation = (p0.a & 0b11000000) >> 6;
    result.FirstNumber = ((p0.a & 0b111111) << 10) | (p0.b << 2) | ((p0.c & 0b11000000) >> 6);
    result.SecondNumber = ((p0.c & 0b111111) << 10) | (p0.d << 2) | ((p0.e & 0b11000000) >> 6);
    result.Status = (p0.e & 0b111000) >> 3;
    result.SessionID = ((p0.e & 0b111) << 5) | ((p0.f & 0b11111000) >> 3);
    result.Answer = p0.f & 0b111;

    return result;
}

这样,您可以查看每个操作并确认它们正确无误

© www.soinside.com 2019 - 2024. All rights reserved.