为什么相同的位集不转换为相同的乌龙
why don't identical bitsets convert to identical ulong
我正在处理std::bitset<16>
向量中的数据,我都必须使用自制函数将其与无符号长(通过std::bitset::to_ulong()
)和字符串相互转换(确切的算法与这个问题无关)
Bitset 向量和字符串之间的转换起初似乎工作正常,因为如果我首先将位集向量转换为字符串,然后再转换回 bitset,它是相同的;我已经通过制作一个包含以下内容的程序来证明这一点:
for (std::bitset<16>& B : my_bitset16vector) std::cout<<B<<std::endl;//print bitsets before conversion
bitset_to_string(my_bitset16vector,my_str);
string_to_bitset(my_bitset16vector,my_str);
std::cout<<std::endl
for (std::bitset<16>& B : my_bitset16vector) std::cout<<B<<std::endl;//print bitsets after conversion
输出可能看起来像这样(在这种情况下只有 4 位集):
1011000011010000
1001010000011011
1110100001101111
1001000011001111
1011000011010000
1001010000011011
1110100001101111
1001000011001111
由此判断,转换前后的位集显然是相同的,但是尽管如此,当我告诉它们转换为无符号长时,位集的转换完全不同;在一个可能看起来像这样的程序中:
for (std::bitset<16>& B : my_bitset16vector) std::cout<<B<<".to_ulong()="<<B.to_ulong()<<std::endl;//print bitsets before conversation
bitset_to_string(my_bitset16vector,my_str);
string_to_bitset(my_bitset16vector,my_str);
std::cout<<std::endl
for (std::bitset<16>& B : my_bitset16vector) std::cout<<B<<".to_ulong()="<<B.to_ulong()<<std::endl;//print bitsets after conversion
输出可能如下所示:
1011000011010000.to_ulong()=11841744
1001010000011011.to_ulong()=1938459
1110100001101111.to_ulong()=22472815
1001000011001111.to_ulong()=18649295
1011000011010000.to_ulong()=45264
1001010000011011.to_ulong()=37915
1110100001101111.to_ulong()=59503
1001000011001111.to_ulong()=37071
首先,很明显,超出所有合理怀疑的位集在显示为二进制时是相同的,但是当转换为无符号长整型时,相同的位集返回完全不同的值(完全毁了我的程序)
这是为什么呢? 难道位集是单一的,即使它们打印为相同? 尽管位集相同,但与字符串转换器之间的位集中是否存在错误?
编辑:并非所有程序,包括我的对话都有这个问题,它只发生在我在创建位集(从字符串)后修改了位集时,在我的情况下,试图加密位集,这根本不能简化为简单而简短的东西,但在我最压缩的写作方式中,它看起来像这样:
(即使不包括公钥结构和模块化电源功能的定义)
int main(int argc, char**argv)
{
if (argc != 3)
{
std::cout<<"only 2 arguments allowed: plaintext user"<<std::endl;
return 1;
}
unsigned long k=123456789;//any huge number loaded from an external file
unsigned long m=123456789;//any huge number loaded from an external file
std::vector< std::bitset<16> > data;
std::string datastring=std::string(argv[1]);
string_to_bitset(data,datastring);//string_to_bitset and bitset_to_string also empties string and bitset vector, this is not the cause of the problem
for (std::bitset<16>& C : data)
{
C =std::bitset<16>(modpow(C.to_ulong(),k,m));//repeated squaring to solve C.to_ulong()^k%m
}
//and now the problem happens
for (std::bitset<16>& C : data) std::cout<<C<<".to_ulong()="<<C.to_ullong()<<std::endl;
std::cout<<std::endl;
bitset_to_string(data,datastring);
string_to_bitset(data,datastring);
//bitset_to_string(data,datastring);
for (std::bitset<16>& C : data) std::cout<<C<<".to_ulong()="<<C.to_ullong()<<std::endl;
std::cout<<std::endl;
return 0;
}
我很清楚,你们现在都认为我做错了模块化电源函数(我保证我没有),但我正在做什么来实现这一目标实际上并不重要,因为我的问题不是:我的程序出了什么问题;我的问题是:为什么相同的位集(打印相同的二进制 1 和 0)不转换为相同的无符号长整型。
其他编辑:我还必须指出,无符号长整型的第一个打印值是"正确的",因为它们在使用时允许我完美地解密位集,而之后打印的无符号长整型的值是"错误的",因为它会产生完全错误的结果。
"11841744"值在较低的 16 位中是正确的,但在第 16 位以上有一些额外的设置位。这可能是 STL 实现中的一个错误,其中to_long访问的位超过它应该使用的 16 位。
或者(从上面的评论中)您向位集添加的位数超过了它可以容纳的位,并且您遇到了未定义的行为。
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- 为什么mpfr_printf与十六进制浮点(%a转换说明符)的printf不同
- 为什么g++在未执行的代码处标记强制转换错误
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 为什么 openmp 的并行不适用于矢量化色彩空间转换?
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 为什么我的模板化函数需要从一个迭代器转换到另一个迭代器?
- 为什么我收到"从常量指针到指针的转换无效?
- 为什么 c++ 不允许(自动)强制转换?
- 为什么即使我没有进行转换,此代码中也有转换?
- 为什么我会收到此错误?无法将 {lb, ub} 从<大括号括起来的初始值设定项列表>转换为 float(**)(float*, int)
- 为什么下面带有非常量转换函数的代码没有歧义?
- 为什么转换函数声明不需要至少一个定义类型说明符
- 为什么此指针值不能转换为整数的规则是什么?
- 为什么在将 void 指针转换为整数指针时出现分段错误
- 在 OS X 上的 ifconfig.h 的 ifadder 结构中,我可以将ifa_data转换为什么?
- 双精度到浮点型转换 -- 为什么我不能将 (双精度)20150813.00 转换为 (浮点型)20150813.00?
- c++隐式转换:为什么字面字符串要转换为字符串
- Reg 文件 - "dword"转换为什么?