C++ 使用位运算符将十进制转换为八进制

C++ 使用位运算符将十进制转换为八进制,c++,octal,base-conversion,C++,Octal,Base Conversion,下面的函数用于将其参数(整数)从十进制转换为八进制 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,它返回77777,此时它应该

下面的函数用于将其参数(整数)从十进制转换为八进制

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
,它返回
77777
,此时它应该返回
37777
,因此第一个数字必须是
3
,而不是
7
。为什么会这样?对于所有负输入,该功能似乎不正确。如何调整算法,使其正确返回负数

注意:这是一个CS作业,因此我希望得到提示。

这是因为算术移位保留了数字的符号。要克服此问题,请首先将输入整数强制转换为等效的无符号类型

((无符号整数)num)>>3*i)和7


更进一步,您可以对函数进行模板化,并使用
sizeof
计算八进制位数(如DanielH所建议的),将指向输入的指针强制转换为
uint8*
。然而,这将是一个更复杂的问题,因为某个数字的位可能会超过两个字节。

ios\u基地和oct(ios\u基地和str)

使用八进制设置str流的基字段格式标志 到十月

示例

// 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;
}

因此,底线是你正在重新发明轮子。

你不更愿意拥有
777
37777
并不意味着八进制中的-1。@rex是32位整数,它是
77777
表示33个1位,而
37777
正确表示32个1位。@rex不确定,但赋值表示
dec_to_oct(-1)
应返回
37777
并且
std::oct还应查看流操纵器。此函数的输入不是十进制。这是一个
int
<代码>标准::我可以更进一步,使参数不带符号。您还应该使用
sizeof(num)*CHAR\u BIT/3
(在可被3整除的情况下进行更正)作为循环的上限,因为在某些系统上
int
可以是64位,甚至更奇怪。@DanielH我知道系统将是带有4字节整数的armv8,但我可以看到这在将来会有什么帮助。另外,如果我使循环参数无符号,则for循环将永远运行。@Dando18我不是要使循环变量
无符号
(尽管如果需要,可以使用
for(unsigned int I=11;I-->0;)
);我的意思是使
num
无符号(
std::string dec_to_oct(unsigned int num)
)。@Dando18因为在
I=0
的循环之后,它将成为无符号类型的最大值,而不是-1,因此循环条件总是满足的。您应该反转循环,并预先填充(而不是追加)新字符:<代码>输出= [Stry+Edvult//Cord> @ MeoGoeSeTeEd狗,但是(C和C++的方式定义事物)一个字节是无论大小< Cuth> char < /C> >。在您可能遇到的任何通用系统上,它都是8位的(除非他们决定在未来的硬件中切换到更大的字节),但是一些模糊的系统有更大的字节,而且无论如何
CHAR\u-BIT
比有幻数要好。我知道这些,然而,这是一个学校作业,需要使用位运算。
70
46
106