整数中的字节顺序控制
硬件层面的各种信息系统在内存中表示数字时,使用不同的字节顺序。因此,当将 MQL 程序与“外部世界”整合时,尤其是当实现网络通信协议或读写常见格式的文件时,可能需要更改字节顺序。
Windows 计算机应用小端模式(从最低有效字节开始),即在为变量分配的内存单元中,首先从最低字节开始,然后是具有更高位的字节,以此类推。互联网上则广泛使用另一种大端模式(从最高位,即最有效字节开始)。在这种情况下,内存单元中的第一个字节是高位字节,而最后一个字节是低位字节。这种顺序类似于我们在日常生活中“从左到右”写数字的方式。例如,值 1234 从 1 开始,代表千位,后面是 2 代表百位,3 代表十位,最后的 4 就是个位四(低序)。
我们看看 MQL5 中的默认字节序。为此,我们将使用 MathSwap.mq5 脚本。
该脚本描述了允许你将整数转换为字节数组的连接模式:
template<typename T>
|
该代码允许你以可视化的方式将数字分为字节,并使用数组中的索引枚举这些字节。
在 OnStart 中,我们以值 0x12345678 描述 uint 变量(注意,数字为十六进制;在该记数法中,它们与字节边界完全对应:每 2 个数位是一个单独的字节)。我们将数字转换为数组,并将其输出到日志。
void OnStart()
|
ArrayPrint 函数不能打印十六进制的数字,因此我们看到的是它们的十进制表示,但可轻松将它们转换为十六进制,以确保它们匹配原始字节。直观来看,它们处于逆反顺序:即,在数组中的 0 号索引是 0x78,然后是 0x56、0x34 和 0x12。很明显,这一顺序是从最低有效字节开始(实际上,我们处于 Windows 环境中)。
现在让我们来熟悉函数 MathSwap,MQL5 提供该函数用于更改字节顺序。
integer MathSwap(integer value)
该函数返回一个整数,其中传入参数的字节顺序被反转。该函数使用 ushort/uint/ulong 类型的参数(即大小为 2、4、8 字节)。
我们以实操的方式来测试该函数:
const uint ui = 0x12345678;
|
结果如下:
12345678 -> 78563412
|
我们尝试在使用 MathSwap 转换值 0x12345678 之后,将字节数组记录到日志:
bo = MathSwap(ui); // put the result of MathSwap into ByteOverlay
|
字节中索引为 0 的位置,之前是 0x78,现在是 0x12,在包含其它数字的元素中,值也已经交换。