在C++编程领域不时出现的一个常见问题是字节序的编译时确定.通常这是通过几乎不可移植的#ifdef来完成的.但是C++ 11 constexpr关键字和模板专业化是否为我们提供了更好的解决方案?
做以下事情是合法的C++ 11:
constexpr bool little_endian()
{
const static unsigned num = 0xAABBCCDD;
return reinterpret_cast<const unsigned char*> (&num)[0] == 0xDD;
}
Run Code Online (Sandbox Code Playgroud)
然后专门为两种endian类型设置模板:
template <bool LittleEndian>
struct Foo
{
// .... specialization for little endian
};
template <>
struct Foo<false>
{
// .... specialization for big endian
};
Run Code Online (Sandbox Code Playgroud)
然后做:
Foo<little_endian()>::do_something();
Run Code Online (Sandbox Code Playgroud) 我有一些关于endian-ness的问题已经足够相关,我保证将它们作为一个问题加入:
1)字节是由.Net还是由硬件决定的?
2)如果由硬件决定,我怎样才能弄清楚硬件在C#中的端点?
3)endian-ness是否影响二进制交互,如OR,AND,XOR或移位?IE将向右移动一次总是偏离最不重要的位?
4)我对此表示怀疑,但不同版本的.Net框架的字节序有何不同?我假设他们都是一样的,但我已经学会停止假设一些较低级别的细节,比如这个.
如果需要,我可以问这些不同的问题,但我认为任何知道其中一个答案的人可能都知道所有人的答案(或者可以指出我的方向).
我已经看到了关于结构的字节序的一些问题和答案,但它们是关于检测系统的字节序,或者在两个不同的字节序之间转换数据.
但是,如果有一种方法可以强制执行给定结构的特定字节顺序,那么我现在想要的是什么.是否有一些好的编译器指令或其他简单的解决方案,除了重写操作在位域上的很多宏的整个事情?
一般的解决方案会很好,但我也会对特定的gcc解决方案感到满意.
编辑:
感谢所有评论指出为什么强制执行endianness不是一个好主意,但在我的情况下,这正是我需要的.
特定处理器生成大量数据(永远不会改变,它是带有自定义硬件的嵌入式系统),并且必须由在未知处理器上运行的程序(我正在处理)读取.对数据进行字节评估会非常麻烦,因为它包含数百种不同类型的结构,这些结构非常庞大且深入:它们中的大多数都有许多其他巨大的结构层.
改变嵌入式处理器的软件是不可能的.源是可用的,这就是为什么我打算使用该系统的结构而不是从头开始并按字节方式评估所有数据.
这就是为什么我需要告诉编译器它应该使用哪个字节序,无论效率与否都无关紧要.
它不一定是字节序的真正变化.即使它只是一个接口,物理上所有东西都是在处理器自己的字节序中处理的,但我完全可以接受.
由于大端和小端与字节顺序有关,并且由于一个u8是一个字节,所以不会u8::from_be_bytes并且u8::from_le_bytes总是具有相同的行为吗?
以下是我在尝试'git svn rebase'时遇到的错误:
Byte order is not compatible at ../../lib/Storable.pm (autosplit into ../../lib/auto/Storable/_retrieve.al) line 380, at /usr/lib/perl5/5.10/Memoize/Storable.pm line 21
Run Code Online (Sandbox Code Playgroud)
我正在运行的perl版本是:
$ perl --version
This is perl, v5.10.1 (*) built for i686-cygwin-thread-multi-64int
(with 12 registered patches, see perl -V for more detail)
Run Code Online (Sandbox Code Playgroud)
当我在网上搜索" 字节顺序不兼容 "时,我收到很多点击,显示Perl文档说:
这意味着,如果您在Unix或Linux上使用64位整数配置的perl 5.6.0或5.6.1上运行的Storable 1.x写入数据,那么默认情况下这个Storable将拒绝读取它,给出错误字节顺序不兼容.如果你有这样的数据,那么你应该将$ Storable :: interwork_56_64bit设置为一个真值,以使这个可存储的读取和写入文件与旧标题.您还应该将您的数据或与之通信的任何旧版perl迁移到当前版本的Storable.
我不知道的是,如何将此设置$Storable::interwork_56_64bit为真.你能告诉我怎么做吗?
我在两个人身上缠着麻烦.我理解如何用big endian表示某些东西.
例如-12是1111 1111 1111 0100
但为什么小端表示1111 0100 1111 1111而不是0100 1111 1111 1111?
我正在尝试用4个复合字节构建一个32位浮点数.有没有比使用以下方法更好(或更便携)的方法?
#include <iostream>
typedef unsigned char uchar;
float bytesToFloat(uchar b0, uchar b1, uchar b2, uchar b3)
{
float output;
*((uchar*)(&output) + 3) = b0;
*((uchar*)(&output) + 2) = b1;
*((uchar*)(&output) + 1) = b2;
*((uchar*)(&output) + 0) = b3;
return output;
}
int main()
{
std::cout << bytesToFloat(0x3e, 0xaa, 0xaa, 0xab) << std::endl; // 1.0 / 3.0
std::cout << bytesToFloat(0x7f, 0x7f, 0xff, 0xff) << std::endl; // 3.4028234 × 10^38 (max single precision)
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我有一个字节数组,其中数组中的数据实际上是短数据.字节以小端顺序排序:
3,1,-48,0,-15,0,36,1
转换为短值时会导致:
259,208,241,292
Java中有一种简单的方法可以将字节值转换为相应的短值吗?我可以编写一个循环,它只占用每个高字节并将其移位8位,并将其与低字节一起使用,但这会影响性能.
我只是想问一下我的方法是否正确,从小端到大端转换,只是为了确保我理解差异.
我有一个存储在little-endian中的数字,这里是数字的二进制和十六进制表示:
?0001 0010 0011 0100 0101 0110 0111 1000?
?12345678?
Run Code Online (Sandbox Code Playgroud)
在big-endian格式中,我认为应该交换字节,如下所示:
1000 0111 0110 0101 0100 0011 0010 0001
?87654321
Run Code Online (Sandbox Code Playgroud)
它是否正确?
此外,下面的代码尝试执行此操作但失败.有什么明显的错误或者我可以优化一些东西吗?如果代码对于此转换有害,请解释原因并展示执行相同转换的更好方法吗?
uint32_t num = 0x12345678;
uint32_t b0,b1,b2,b3,b4,b5,b6,b7;
uint32_t res = 0;
b0 = (num & 0xf) << 28;
b1 = (num & 0xf0) << 24;
b2 = (num & 0xf00) << 20;
b3 = (num & 0xf000) << 16;
b4 = (num & 0xf0000) << 12;
b5 = (num & 0xf00000) << 8;
b6 = (num & 0xf000000) …Run Code Online (Sandbox Code Playgroud) 为什么这个程序的输出是4?
#include <iostream>
int main()
{
short A[] = {1, 2, 3, 4, 5, 6};
std::cout << *(short*)((char*)A + 7) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,在x86 little endian系统上,char有1个字节,短2个字节,输出应该是0x0500,因为数组中的数据A是十六进制的休闲:
01 00 02 00 03 00 04 00 05 00 06 00
Run Code Online (Sandbox Code Playgroud)
我们从开始向前移动7个字节,然后读取2个字节.我错过了什么?