Я пишу свою маленькую библиотеку с множественными точностями, и при написании метода для вычитания я обнаружил странную ошибку. Вот блок кода, для которого я написал для вычитания мультиточности:
/* subtraction */
for (; p_aReverseIter != a.m_elements.rend(); ++p_aReverseIter, ++p_bReverseIter)
{
temp = static_cast<__int64>(static_cast<__int64>(p_aReverseIter->m_Value) -
static_cast<__int64>(p_bReverseIter->m_Value) +
(carry));
--- debug output-
p_aReverseIter->m_Value = static_cast<unsigned int>(temp & 0xffffffff);
carry = static_cast<unsigned long>(temp >> 32);
}
p_aReverseIter-> m_Value - 32-битное целое число без знака, а a, b - BigInt. Значения хранятся внутри вектора в стиле Big Endian.
temp равен __int64, и значение carry должно работать как 32-битное без знака.
Допустим, мы вычитаем b из a, a> b (вычитание без знака), но все 32-битные слова в b больше, чем a. Эта процедура выдает следующий вывод:
a = 0xfefefefe (10 elem) 0xfefefefe (10 elem) 0xfefefefe (10 elem)
0xfefefefe (10 elem)
b = 0x12 (2 elem) 0x12121212 (9 elem) 0x12121212 (9 elem) 0x12121212
(9 elem) 0x12121212 (9 elem)
a[i]: 12121212
b[i]: fefefefe
old carry: 0
temp = a - b + carry: ffffffff13131314
Value: 13131314
new carry: ffffffffffffffff
a[i]: 12121212
b[i]: fefefefe
old carry: ffffffff
temp = a - b + carry: 13131313
Value: 13131313
new carry: 0
a[i]: 12121212
b[i]: fefefefe
old carry: 0
temp = a - b + carry: ffffffff13131314
Value: 13131314
new carry: ffffffffffffffff
a[i]: 12121212
b[i]: fefefefe
old carry: ffffffff
temp = a - b + carry: 13131313
Value: 13131313
new carry: 0
...
Но перенос всегда должен быть 0xfffffffff. Каждый раз, когда он равен нулю, результатом является «13131314», что неверно. Теперь давайте изменим перенос с unsigned long на unsigned __int64 и
carry = static_cast<unsigned long>(temp >> 32);
до
carry = static_cast<unsigned __int64>(temp >> 32);
Теперь перенос всегда рассчитывается правильно и имеет значение 0xffffffff.
Но смещение прав на 64-битное значение 2 ^ 32 всегда должно давать 32-битный результат.
Мой вопрос: чтобы понять разные результаты, чего мне не хватает?
Большое спасибо.