Преобразование десятичного числа в восьмеричное с использованием побитовых операторов

Приведенная ниже функция предназначена для преобразования ее параметра целого числа из десятичного в восьмеричное.

std::string dec_to_oct(int num) {
std::string output;
for(int i=10; i>=0; --i) {
output += std::to_string( (num >> i*3) & 0b111 );
}
return output;
}

Это работает для любого положительного вклада, однако, для num = -1 это возвращается 77777777777когда он должен вернуться 37777777777поэтому первая цифра должна быть 3 вместо 7, Почему это происходит? Функция кажется неправильной для всех отрицательных входных данных. Как я могу настроить алгоритм так, чтобы он правильно возвращал отрицательные числа?

Замечания: это задание CS, поэтому я буду признателен за советы / подсказки.

1

Решение

Это потому что арифметический сдвиг сохраняет знак числа. Чтобы преодолеть это, сначала приведите входное целое число к эквивалентному типу без знака.

(((unsigned int)num) >> 3*i) & 7


Идя дальше, вы можете сделать функцию шаблонной и привести указатель к входу uint8_t*, с помощью sizeof рассчитать количество восьмеричных цифр (согласно предложению DanielH). Однако это будет немного сложнее, поскольку биты для определенной цифры могут растягиваться на два байта.

2

Другие решения

Копировать вставить документацию

ios_base& окт (ios_base& ул);

Использовать восьмеричное основание Устанавливает basefield флаг формата для ул поток
в октябрь.

пример

// modify basefield
#include <iostream>     // std::cout, std::dec, std::hex, std::oct

int main () {
int n = 70;
std::cout << std::dec << n << '\n';
std::cout << std::hex << n << '\n';
std::cout << std::oct << n << '\n';
return 0;
}

Выход:

70
46
106

Итак, суть в том, что вы заново изобретаете колесо.

0