为了账号安全,请及时绑定邮箱和手机立即绑定

如何在C+中的大端值和小端点值之间进行转换?

如何在C+中的大端值和小端点值之间进行转换?

C++ C
慕容3067478 2019-06-12 21:22:05
如何在C+中的大端值和小端点值之间进行转换?如何在C+中的大端值和小端点值之间进行转换?编辑:为了清晰起见,我必须将二进制数据(双精度浮点值和32位和64位整数)从一个CPU体系结构转换到另一个CPU体系结构。这不涉及联网,因此Ntoh()和类似的函数在这里不能工作。编辑2:我接受的答案直接适用于我正在获取的编译器(这就是我选择它的原因)。然而,这里还有其他更好、更便携的答案。
查看完整描述

3 回答

?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

如果你用Visual C+执行以下操作:包含in.h并调用以下函数:

对于16位数:

unsigned short _byteswap_ushort(unsigned short value);

对于32位数:

unsigned long _byteswap_ulong(unsigned long value);

对于64位数:

unsigned __int64 _byteswap_uint64(unsigned __int64 value);

8位数字(字符)不需要转换。

此外,这些也只为它们为有符号整数工作的无符号值定义。

对于浮点数和双面数,就像普通整数一样,难度更大,因为这些整数可能是按主机字节顺序排列的,也可能不按字节顺序排列。你可以在大端机器上得到小终端浮点数,反之亦然.

其他编译器也有类似的本质。

在……里面GCC例如,您可以直接调用:

int32_t __builtin_bswap32 (int32_t x)int64_t __builtin_bswap64 (int64_t x)

(不需要包括什么)。h也以一种非GCC中心的方式声明相同的函数。

16位交换,只是一点点旋转。

调用本质,而不是滚动自己的,给你最好的性能和代码密度,顺便说一句。


查看完整回答
反对 回复 2019-06-12
?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

简单地说:

#include <climits>template <typename T>T swap_endian(T u){
    static_assert (CHAR_BIT == 8, "CHAR_BIT != 8");

    union
    {
        T u;
        unsigned char u8[sizeof(T)];
    } source, dest;

    source.u = u;

    for (size_t k = 0; k < sizeof(T); k++)
        dest.u8[k] = source.u8[sizeof(T) - k - 1];

    return dest.u;}

用法:swap_endian<uint32_t>(42).


查看完整回答
反对 回复 2019-06-12
?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

从…拜德秩序谬误罗布·派克:

假设您的数据流有一个端编码的32位整数。下面是如何提取它(假设没有签名的字节):

i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);

如果它是大端,下面是如何提取它:

i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);

TL;DR:不要担心您的平台原生顺序,所有重要的是您正在读取的流的字节顺序,您最好希望它有良好的定义。

注:注释中指出,如果没有显式类型转换,则重要的是data是一个数组unsigned charuint8_t..使用signed charchar(如果签署)将导致data[x]被提升为整数和data[x] << 24可能将1移动到符号位,即UB。


查看完整回答
反对 回复 2019-06-12
  • 3 回答
  • 0 关注
  • 1844 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信