Каков наилучший метод для возврата длинного знака без знака из вектора целых чисел? Я работаю над классом BigInt в c ++ и храню большие числа в векторе. Я хочу написать метод, который будет возвращать этот вектор как стандартное длинное при условии, что он не больше, чем может хранить беззнаковое длинное. Спасибо
Что-то вроде этих линий, предполагая, что целые числа хранятся в векторе с наименее значимым первым:
size_t bits_in_int = std::numeric_limits<int>::digits;
size_t bits_in_ulong = std::numeric_limits<unsigned long>::digits;
unsigned long accumulator = 0;
size_t bits_so_far = 0;
for (unsigned long i : the_ints) {
size_t next_bits = bits_so_far + bits_in_int;
if (next_bits > bits_in_long) { /* failed, do something about it */}
accumulator += (i << bits_so_far);
bits_so_far = next_bits;
}
return accumulator;
Заметки:
1) На практике вы могли бы сэкономить некоторые хлопоты, потому что число циклов будет равно 1 или 2 в любой неопределенно выглядящей реализации C ++. Таким образом, вы могли бы просто написать случай, когда вы вернетесь the_ints[0]
и случай, когда вы вернетесь the_ints[0] + (the_ints[1] << bits_in_int)
,
2) Я был ленив. Так как int
подписан и unsigned long
без знака, вы можете соответствовать хотя бы одному int
плюс наименее значимый бит другого int
в unsigned long
, Например, вы можете найти bits_in_int
31 но bits_in_long
32
Так что на самом деле в «провалившемся» случае есть последняя надежда на мир, а именно: (а) есть только одна int
осталось обработать, и (b) его значение вписывается в остальные биты результата. Но, как я уже сказал, я ленивый, и я думаю, что я показал компоненты, которые нужно собрать.
По этой причине, если нет других, вы, вероятно, должны использовать вектор unsigned int
для вашего BigInt. Не требуется, чтобы ширина unsigned long
кратно числу битов в unsigned int
, но это может быть достаточно странно, что вы можете игнорировать это.
Обновление для базовых 10 цифр, сохраненных наиболее значимыми первыми:
if (the_ints.size() <= std::numeric_limits<unsigned long>::digits10 + 1) {
std::stringstream ss;
for (int i : the_ints) ss << char(i + '0');
unsigned long result;
if (ss >> result) return result;
}
/* failed, do something about it */
Других решений пока нет …