C++ 如何将boost多精度整数从小端数转换为大端数?
因为 因为以太坊是一台大端机器,所以您的顺序可能是错误的(地址正确表示,因为它们使用较小的类型)。C++ 如何将boost多精度整数从小端数转换为大端数?,c++,boost,c++14,endianness,boost-multiprecision,C++,Boost,C++14,Endianness,Boost Multiprecision,因为 因为以太坊是一台大端机器,所以您的顺序可能是错误的(地址正确表示,因为它们使用较小的类型)。 另一种方法是运行protocolity.exe--code'0x61004b60026319e44e32'--disassm u256类型定义为 using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsign
另一种方法是运行
protocolity.exe--code'0x61004b60026319e44e32'--disassm
u256
类型定义为
using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
现在,为什么我的256位整数大部分打印为
00
系列 顺便说一句,这不是一个持久性问题;您没有对对象表示进行字节访问。您将其作为256位整数进行操作,只需使用data&0xFF
一次请求低8位
如果您确实知道目标C实现的endianness,以及boost
对象的数据布局,那么您可以使用unsigned char*
以降序地址顺序高效地循环它
您之所以引入endianness的概念,只是因为它与字节反转相关,而这正是您所要做的但这样做效率很低,只需以另一种方式循环bigint的字节即可。
我不敢推荐一个具体的解决方案,因为我不知道什么能有效地编译。但是您可能需要这样的内容,而不是提前进行字节反转:
for (outer loop) {
uint64_t chunk = data >> (64*3); // grab the highest 64-bit chunk
data <<= 64; // and shift everything up
// alternative: maybe keep a shift-count in a variable instead of modifying `data`
// Then pick apart the chunk into its component bytes, in MSB first order
for (int = 0 ; i<8 ; i++) {
unsigned tmp = (chunk >> 56) & 0xFF;
// do something with it
chunk <<= 8; // bring the next byte to the top
}
}
如果你想把它分成几块,在里面放一个换行符,你也可以这样做
如果您对同时将8、16或32字节的数据高效转换为十六进制感兴趣,请参阅,了解一些x86 SIMD方式。ASM应该很容易地移植到C++内部。(您可以使用SIMD shuffles处理从小端整数加载后将字节放入MSB的第一个打印顺序。) 在存储到内存之前,您还可以使用SIMD shuffle来分隔十六进制数字对,就像您在这里显然想要的那样
您添加的代码中的错误: 因此,我在上面的循环之前添加了以下代码:
for(unsigned int i=0,data,_data;i<33;++i)
用于(unsigned int i=0,data,_data;我建议在数字上向后循环,以获得最高的chunk first/MSD first打印顺序,而不是对32字节对象进行字节反转。此外,您可以使用uint64_t
,因此您只需要对操作符进行4个chunk/4个单独调用,顺便说一句,这不是一个尾数问题;您没有进行字节ac访问对象表示。您将其作为256位整数进行操作,并且一次只要求低8位。如果您确实知道目标C实现的endianness和对象的数据布局,您可以使用unsigned char*
@PeterCordes ok以降序地址顺序在其上循环。我固定了字节顺序循环的迭代。但我仍然有完全相同的问题(即使打印不包含零的数字)。我可以说,当打印时,内部表示完全正确地打印预期的数字(好像long
是本机编译器类型)但以小尾端顺序。使用8字节块的方法,每个64位块中的数字不应该以错误的字节顺序存在吗?@user2284570:什么不起作用?你还在试图修复低效的字节反向循环吗?是的,每次执行要打印2个数字,我不需要它来提高效率。我编辑了问题n范围错误得到纠正(新循环中的数字似乎是随机的)(同样没有字节顺序循环,它们被正确写入ASCII,但字节顺序错误)。@user2284570:My nested loops以最重要的第一顺序一次提取一个数据的字节。这不是“错误”顺序,就是数字的工作方式。打印顺序首先是最高的,因为英文书写系统是从左到右的,而我们的数字书写系统是基于位值阿拉伯数字的,位值阿拉伯数字将最重要的数字放在左边。所以我们需要在第一个字节打印最重要的8位。这不是“错”。您使用该嵌套循环,而不是反转256位数字的字节,然后以LSB第一顺序打印它。我从一开始就在谈论打印英文文本。例如,31722是在我的机器上编写的8a 02
,在为大端目标编译时编写的02 02 8a
。因此,我需要转换数据从小端表示到大端/网络字节顺序。StringStream在所有程序中都是共享的,所以虽然我可以使用boost库来实现这一点,但我没有找到它的函数。
for (outer loop) {
uint64_t chunk = data >> (64*3); // grab the highest 64-bit chunk
data <<= 64; // and shift everything up
// alternative: maybe keep a shift-count in a variable instead of modifying `data`
// Then pick apart the chunk into its component bytes, in MSB first order
for (int = 0 ; i<8 ; i++) {
unsigned tmp = (chunk >> 56) & 0xFF;
// do something with it
chunk <<= 8; // bring the next byte to the top
}
}
// 97 = 32 * 2 + 32, plus 1 byte for an implicit-length C string terminator
// plus another 1 for an extra space
char buf[98]; // small enough to use automatic storage
char *outp = buf+96; // pointer to the end
*outp = 0; // terminator
const char *hex_lut = "0123456789abcdef";
for (int i=0 ; i<32 ; i++) {
uint8_t byte = data & 0xFF;
*--outp = hex_lut[byte >> 4];
*--outp = hex_lut[byte & 0xF];
*--outp = ' ';
data >>= 8;
}
// outp points at an extra ' '
outp++;
// outp points at the first byte of a string like "12 ab cd"
stream << outp;
for(unsigned int i=0,data,_data;i<33;++i)