网络通讯大小端转换c/c++

        日常生活中常见的设备基本上都是小端系统,在同类设备(同为大端,或者同为小端)之间的通讯不需要考虑大小端问题,但是工业中有些生产商仍然会沿用大端系统,当在不同类设备之间通讯时,必须考虑多字节数据(short, int32,int64, float, double等)的字节序问题。不同的开发语言和不同的操作系统可能有自己的大小端转换接口,如果是c/c++程序开发,则可以借鉴下面的转换代码,对5种基本类型进行转换(虽然形参为有符号数,但是即便传递无符号数,也是可以正确转换的)。

        注:如果是大端,则返回小端;如果是小端,则返回大端。

#pragma once

class LittleEndianConverter
{
public:
    static __int16 Cpu_Short_To_BLe16(const __int16 v);
    static __int32 Cpu_Int_To_BLe32(const __int32 v);
    static float Cpu_Float_To_BLe32(const float v);
    static __int64 Cpu_Int_To_BLe64(const __int64 v);
    static double Cpu_Double_To_BLe64(const double v);
};


typedef union FLOAT_CONV
{
    float                f;
    char                c[4];
}FLOATCONV;

typedef union DOUBLE_CONV
{
    double                d;
    char                c[8];
}DOUBLECONV;

__int16 LittleEndianConverter::Cpu_Short_To_BLe16(const __int16 v)
{
    //负数执行右移时左边会补1,即执行的是算数位移而非逻辑位移,因此要&0x00ff以消除高位的1
    return ((v & 0xff) << 8) | (v >> 8 & 0x00ff);
}

__int32 LittleEndianConverter::Cpu_Int_To_BLe32(const __int32 v)
{
    return ((v >> 24) & 0x000000ff)
        | ((v & 0x00ff0000) >> 8 & 0x00ffffff)
        | ((v & 0x0000ff00) << 8)
        | (v << 24);
}

__int64 LittleEndianConverter::Cpu_Int_To_BLe64(const __int64 v)
{
    return ((v >> 56) & 0x00000000000000ff)
        | ((v & 0x00ff000000000000) >> 40 & 0x0000000000ffffff)
        | ((v & 0x0000ff0000000000) >> 24 & 0x000000ffffffffff)
        | ((v & 0x000000ff00000000) >> 8 & 0x00ffffffffffffff)
        | ((v & 0x00000000ff000000) << 8)
        | ((v & 0x0000000000ff0000) << 24)
        | ((v & 0x000000000000ff00) << 40)
        | (v << 56);
}

float LittleEndianConverter::Cpu_Float_To_BLe32(const float v)
{
    /*
    unsigned __int32 Tempval;
    unsigned __int32 Retval;
    float rv;
    Tempval = *(unsigned __int32*)(&v);
    Retval = Cpu_Int_To_BLe32(Tempval);
    *((unsigned __int32*)(&rv))=Retval;
    return rv;// works well
    */
    FLOATCONV conv1, conv2;
    conv1.f = v;
    conv2.c[0] = conv1.c[3];
    conv2.c[1] = conv1.c[2];
    conv2.c[2] = conv1.c[1];
    conv2.c[3] = conv1.c[0];
    return conv2.f;
}

double LittleEndianConverter::Cpu_Double_To_BLe64(const double v)
{
    /*
    unsigned __int64 Tempval;
    unsigned __int64 Retval;
    double rv;
    Tempval = *(unsigned __int64*)(&v);
    Retval = Cpu_Int_To_BLe64(Tempval);
    *((unsigned __int64*)(&rv))=Retval;
    return rv;// works well
    */
    DOUBLECONV conv1, conv2;
    conv1.d = v;
    conv2.c[0] = conv1.c[7];
    conv2.c[1] = conv1.c[6];
    conv2.c[2] = conv1.c[5];
    conv2.c[3] = conv1.c[4];
    conv2.c[4] = conv1.c[3];
    conv2.c[5] = conv1.c[2];
    conv2.c[6] = conv1.c[1];
    conv2.c[7] = conv1.c[0];
    return conv2.d;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值