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

时间:2016-11-29 18:09:40

标签: c++ type-conversion bitset

我正在处理std::bitset<16>向量中的数据,我必须使用自制函数将无符号长(通过std::bitset::to_ulong())和来自字符串的字符串进行转换(精确算法对于这个问题是无关紧要的)

bitset vector和string之间的转换起初似乎工作正常,因为如果我首先将bitsets的向量转换为string然后再转换为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

首先很明显,当显示为二进制时,仍然超出所有合理怀疑的位集是相同的,但是当转换为无符号长整数时,相同的位集返回完全不同的值(完全毁了我的程序)

这是为什么?即使它们的打印方式相同,它们是不一致的吗?虽然位集相同,但我的bitset中是否存在错误存在于字符串转换器中?

编辑:并非包括我的对话在内的所有程序都有这个问题,只有在我创建它(从字符串)后修改了bitset时才会发生这种情况,在我的情况下尝试加密bitset,这根本无法切割简单而简短,但在我最压缩的写作方式中,它看起来像这样:

(甚至没有包括公钥结构和模块化功能函数的定义)

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; s和0&#39; s)转换为相同的无符号长整数。

其他编辑:我还必须指出,unsigned longs的第一个printet值是&#34;正确&#34;因为它们在使用时允许我完美地解密bitset,而之后打印的unsigned longs的值是&#34;错误&#34;因为它会产生完全错误的结果。

1 个答案:

答案 0 :(得分:2)

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

或者(从上面的评论中)你为bitset添加的位数多于它可以容纳的位数,并且你遇到了未定义的行为。