为什么 to_be_bytes() 和 to_le_bytes() 与我在这里期望的相反?
Why does to_be_bytes() and to_le_bytes() do the opposite of what I expect here?
也许问题应该是“为什么我期望 to_be_bytes() 和 to_le_bytes() 在这里做相反的事情?”,但无论如何,情况是这样的:
fn main() {
let buf: [u8; 2048] // Buffer I use to receive UDP messages
let (_, entry, _) = unsafe { buf[14..].align_to::<u16>() };
// In memory entry looks like: 00 44 16 15 21 04 03 5a 03 67 03 6a 03 64 88 91
let [first, second] = entry[0].to_be_bytes();
assert_eq!(first, 0x44);
assert_eq!(second, 0x00);
}
不应该相反吗? big endianness不是像在内存中保留顺序吗?
大端意味着高字节在前存储(或传输)在最低地址。 Intel处理器是little endian,意思是低字节存储在低地址。
每个都有一些优点,但通常首选大端,这就是为什么网络协议和可移植数据格式通常是大端。为了与旧版本兼容,英特尔保留了小端。一些 CPU 具有可以在两者之间切换的模式,但英特尔从未这样做过。
很难确切知道您的期望出了什么问题,但我会尽力解释这里发生的事情。
当您执行 buf.align_to()
时,没有进行任何转换,字节按原样重新解释。所以 entry[0]
(假设它 是 对齐的)将在内存中存储为 00 44
。您的系统可能是小端架构,因此 entry[0]
的 value 是 17408
.
fn main() {
let buf = [0x00, 0x44];
let result = u16::from_ne_bytes(buf); // also doesn't try to reinterpret bytes
assert_eq!(result, 17408);
}
所以现在,entry[0]
是小端系统上的 u16
,表示值 17408
。要使用大端表示法获得相同的值,如 to_be_bytes()
所做的那样,它将交换字节。
考虑到您的网络通信用例,其中通常以大端顺序对值进行编码,您可能希望使用 entry[0].from_be()
来获取 68
.[=22 的正确值=]
也许问题应该是“为什么我期望 to_be_bytes() 和 to_le_bytes() 在这里做相反的事情?”,但无论如何,情况是这样的:
fn main() {
let buf: [u8; 2048] // Buffer I use to receive UDP messages
let (_, entry, _) = unsafe { buf[14..].align_to::<u16>() };
// In memory entry looks like: 00 44 16 15 21 04 03 5a 03 67 03 6a 03 64 88 91
let [first, second] = entry[0].to_be_bytes();
assert_eq!(first, 0x44);
assert_eq!(second, 0x00);
}
不应该相反吗? big endianness不是像在内存中保留顺序吗?
大端意味着高字节在前存储(或传输)在最低地址。 Intel处理器是little endian,意思是低字节存储在低地址。
每个都有一些优点,但通常首选大端,这就是为什么网络协议和可移植数据格式通常是大端。为了与旧版本兼容,英特尔保留了小端。一些 CPU 具有可以在两者之间切换的模式,但英特尔从未这样做过。
很难确切知道您的期望出了什么问题,但我会尽力解释这里发生的事情。
当您执行 buf.align_to()
时,没有进行任何转换,字节按原样重新解释。所以 entry[0]
(假设它 是 对齐的)将在内存中存储为 00 44
。您的系统可能是小端架构,因此 entry[0]
的 value 是 17408
.
fn main() {
let buf = [0x00, 0x44];
let result = u16::from_ne_bytes(buf); // also doesn't try to reinterpret bytes
assert_eq!(result, 17408);
}
所以现在,entry[0]
是小端系统上的 u16
,表示值 17408
。要使用大端表示法获得相同的值,如 to_be_bytes()
所做的那样,它将交换字节。
考虑到您的网络通信用例,其中通常以大端顺序对值进行编码,您可能希望使用 entry[0].from_be()
来获取 68
.[=22 的正确值=]