为什么相同的位集不转换为相同的 ulong

why don't identical bitsets convert to identical ulong

我正在处理 std::bitset<16> 向量中的数据,我都必须使用自制函数与 unsigned long(通过 std::bitset::to_ulong())和字符串进行相互转换(具体算法与本题无关)

bitset 向量和字符串之间的转换起初似乎工作正常,因为如果我首先将 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

据此判断,转换前后的bitsets显然是相同的,但是尽管如此,当我告诉它们转换为unsigned long时,bitsets转换完全不同;在一个看起来像这样的程序中:

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

首先很明显,当显示为二进制时,位集仍然毫无疑问是相同的,但是当转换为无符号长整数时,完全相同 bitsets return 完全不同的值(完全毁了我的程序)

这是为什么?难道 bitsets 是不一样的,即使它们打印的一样?尽管位集 相同?

,但我的位集与字符串转换器之间是否存在错误

编辑:并非包括我的对话在内的所有程序都有这个问题,只有当我在创建比特集(从字符串)后修改它时才会发生,在我的例子中是试图加密比特集,这根本不能被简化为简单而简短的内容,但以我最压缩的方式编写它看起来像这样:

(甚至不包括 public 键结构和模块化幂函数的定义)

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)不转换为相同的无符号长整数。

其他编辑:我还必须指出,unsigned longs 的第一个 printet 值是 "correct" 因为它们在使用时允许我完美地解密位集,而随后打印的 unsigned longs 的值是 "wrong" 因为它产生了一个完全错误的结果。

“11841744”值在低 16 位中是正确的,但在第 16 位以上有一些额外的设置位。这可能是您的 STL 实现中的一个错误,其中 to_long 访问超过它应该使用的 16 位。

或者(根据您上面的评论)您向位集添加的位数超出了它的容量,并且您遇到了未定义的行为。