Endianness in programming languages
好吧,"字节序"主题总是让我有些困惑,但是我从来没有遇到过任何问题,这些问题甚至需要我考虑一下我使用的二进制编写器/读取器的默认行为。我现在正在用C#编写PNG解码器。 PNG文件格式规范指出,所有数字都以大尾数法表示(我觉得很自然)。但是,当我注意到.NET的BinaryReader / Writer使用一点尾数表示法时,我感到非常惊讶。更让我感到困惑的是,事实是Java的二进制IO使用大端符号(不是Java程序员,所以我可能是错的)。所以我开始考虑以下问题:
1-为什么情况如此?我的意思是基类库的默认行为。
2-为什么在使用.NET的System.IO时无法选择首选符号?
我目前正在使用Jon Skeet的MiscUtil,它的工作原理就像一个吊饰(感谢man =)。但是在基类库中看到此功能将很酷。
-
什么是BCL ..?
-
基类库
-
我还发现大尾数法是最自然的。
这是因为该代码应尽可能在最重要的平台上运行。 C#/。NET来自Microsoft,主要在x86平台上运行。 x86是低位优先的,因此使库成为低位优先是有意义的。 Java是由Sun制造的,而Sun SPARC是big-endian的,因此Java标准是big-endian的。
-
紧凑和微框架又如何呢?即使我同意这可能是一个因素,.NET的本质还是与平台无关。
-
Java被设计为与平台无关,这就是为什么它们采用更自然的顺序的原因。 .NET其次是其平台独立性,其主要目的是标准化Windows平台上的各种语言并带来更新的语言功能(如垃圾收集等)。MS/ intel世界通常以这种方式近视,因此大多数Windows程序员将读取的文件为小端。小端字节序是/是英特尔芯片上的首选排序。
-
+1好吧,这当然是合理的,但仍然不能解释选择的缺失。以非常有效的方式在BCL中实现这一点毫无价值。
-
同意在Java中,选择也不是100%直截了当地……我自己已经从该语言中读取了很多小端文件。
-
您绝对可以选择。您可以使用Java。
-
我必须承认,来自SPARC架构的big-endian是我的猜测。但是我愿意将钱押在比大端字节更"自然"重的政治/经济问题上。
-
<耸肩>在我自己的软件生涯中很长一段时间," little endian"也被称为" intel字节排序"。很容易说"大尾数法"对人类来说更自然……以10为底,这就是我们的写作方式。借助x86循环体系结构,"小尾数"在当时对于该体系结构无疑是更有效的。但是,似乎其他所有体系结构都好像是大字节序。
-
@PSpeed对谁更自然? mov 42注册您如何自然检查...
BCL包含System.BitConverter静态类中的内容,使您可以处理系统字节序。结果,BitConverter中的所有方法本质上都是平台无关的。
另外,System.Net.IPAddress.NetworkToHostOrder方法允许您将字节序从大字节序更改为小字节序,反之亦然。
-
除了IsLittleEndian属性以外的其他内容吗?虽然System.Net.IPAddress.NetworkToHostOrder与实际问题相去甚远
-
我不确定我是否理解您的问题。我一直使用BinaryReader和BinaryWriter读写二进制文件,如果字节顺序没有按照我想要的方式进行读写,则只需交换字节(通常使用NetworkToHostOrder)。有什么大不了的?
-
好吧,没有实际问题。确实,您可以在.NET中使用PNG,所以我认为.NET核心开发人员也没有问题。但是我也担心,在运行中(读时)正确地解释字节而无需进一步反转会更有效。当然,我自己很难实现,但是我认为应该在框架内提供这些东西,只是因为它们很常见(这说明了诸如MiscUtil之类的东西的存在)。我实际上想弄清楚的唯一一件事是,有一些严重的原因,为什么我们在NET中没有这个原因?
-
NetworkToHostOrder非常快。我必须相信,从文件中读取字节所需的时间至少比翻转字节所需的时间长两个数量级。
我认为归结为始终能够同时处理这两者,无论您使用的平台是什么。 Preon试图通过允许您声明性地(使用批注)定义内存中数据表示形式与编码表示形式之间的映射,来掩饰某些复杂性。
因此,如果这是您的数据结构的一部分:
1 2 3 4
| public Image {
int width;
int height;
} |
然后定义到自然的大端序表示的映射将很容易:
1 2 3 4
| public Image {
@BoundNumber int width;
@BoundNumber int height;
} |
但是,如果表示形式为小端,则可以执行以下操作:
1 2 3 4
| public Image {
@BoundNumber(byteOrder=LittleEndian) int width;
@BoundNumber(byteOrder=LittleEndian) int height;
} |
在这两种情况下,为此数据结构创建编解码器都是相同的:
1
| Codec<Image> codec = Codecs.create(Image.class); |
我知道有些人也在谈论将其移植到.NET。