简单的操作员+问题逃避了我

时间:2011-06-26 19:06:27

标签: c++ math operator-overloading

我正在尝试添加两个uint8_t列表,就像列表是单个整数一样,我得到了一些奇怪的值:

0x1000 + 0x100 + 0x10 -> 0x1210 ?????

代码如下:

// values 0x123456 stored as: {12, 34, 56}
integer operator+(integer rhs){
    // internal list called 'value'
    std::list <uint8_t> top = value, bottom = rhs.value;
    if (value.size() < rhs.value.size())
        top.swap(bottom);
    top.push_front(0);                           // extra byte for carrying over
    while (bottom.size() + 1 < top.size())       // match up the byte sizes, other than the carry over
        bottom.push_front(0);
    bool carry = false, next_carry = false;
    for(std::list <uint8_t>::reverse_iterator i = top.rbegin(), j = bottom.rbegin(); j != bottom.rend(); i++, j++){
        next_carry = (((uint8_t) (*i + *j + carry)) <= std::min(*i, *j));
        *i += *j + carry;
        carry = next_carry;
    }
    if (carry)
        *top.begin() = 1;
return integer(top);
}

有人能告诉我我做错了吗?

4 个答案:

答案 0 :(得分:3)

考虑添加两个零位数时会发生什么,并且没有进位。 *i + *j + carry == 0<= than min(*i, *j)。因此,你正在产生一股空气。

如果您知道自己只使用字节,则可以将*i + *j + carry存储在int中,然后随身携带sum / 256

答案 1 :(得分:3)

在您的示例(0x100 + 0x10)中,您从carry = false*top.rbegin() = 0*bottom.rbegin() = 0开始。当我们进入循环时,我们会看到以下测试:

next_carry = (((uint8_t) (*i + *j + carry)) <= std::min(*i, *j));
// given *i == 0, *j == 0, and carry == false
// this will evaluate to TRUE

由于next_carry转到下一个添加内容,您最终会得到carry = true,而它应该是false将条件切换为< std::min(*i, *j)

答案 2 :(得分:2)

next_carry = ((*i + *j + carry) > 255);是正确的答案,因为额外的1,因为*i + *j + carry可以等于最小std::min(*i, *j)

答案 3 :(得分:0)

maxval成为uint8_t的最大值。 确定next_carry的存在如下:

next_carry = false;
if( *i == maxval && ( *j > 0 || carry ) ) // excluding *i + carry > maxval case in next if
        next_carry = true;
    else
        if( *i + carry > maxval - *j ) ///  equal to *i + *j + carry > maxval
             next_carry = true;