十进制到二进制,没有数组和二进制运算符(如"&")
Decimal to binary without arrays and binary-operators (like "&")
我必须为大学做一项任务,编写一个将十进制数转换为二进制数的程序。由于我只是计算机科学的初级课程,所以还没有引入数组或逐位运算符(如"&"(。该程序需要仅使用基本运算符(+、-、*、%(和(如果为else,则为(编写。我的方法如下,但我总是得到相反的值。所以不是11000011。
#include <iostream>
int main()
{
int n,a;
std::cin >> n;
for (int i=n; n>0; --i) {
a = n%2;
std::cout << a;
n = n/2;
}
return 0;
}
有办法解决这个问题吗?
当前代码检查从LSB到MSB的二进制值是否存在,并按该顺序打印。解决这个问题的一种方法是从MSB到LSB进行检查。
#include <iostream>
int main(){
int n, a=1;
std::cin >> n;
while(2*a <= n)
a *= 2;
while(a > 0){
if (n >= a){
std::cout << 1;
n -= a;
} else {
std::cout << 0;
}
a /= 2;
}
std::cout << std::endl;
return 0;
}
这不是一个很好的方法,我建议改进它或寻找替代品作为练习。
如果你知道你只能向后得到正确的输出,那么想想你能做些什么来解决这个问题。只需反转位即可。这里有一种只使用基本功能的方法。
#include <iostream>
int main()
{
int n,a;
int bitCount = 0;
std::string reversedBits;
std::cin >> n;
for (int i=n; n>0; --i) {
a = n % 2;
reversedBits += a + '0';
++bitCount;
n = n / 2;
}
for (int i = bitCount - 1; i >= 0; --i) {
std::cout << reversedBits[i];
}
return 0;
}
这并不是说这是最好的方法。找出几个解决这个问题的方法对你来说是一个很好的练习。
我将提出一个非常简单的解决方案,它本质上是纯算术的,不涉及任何可以用来解决这个问题的位级破解,也不涉及类中未涉及的数组。正如你所观察到的,你的方法会反过来给你一个二进制数。不要直接打印得到的数字,而是使用整数将计算的数字放在正确的位置,以正确的顺序保存计算的数字。
考虑一下这个片段:
#include <iostream>
int main()
{
int n,a;
int result = 0;
int position = 1;
std::cin >> n;
for (int i=n; n>0; --i) {
a = n%2;
n = n/2;
result += position * a;
position *= 10;
}
std::cout << result << std::endl;
return 0;
}
追踪输入12的示例:
- 第一次迭代:a为零,因此Result=0,位置从1更新为10
- 第二次迭代:a再次为零,因此Result=0,位置从10更新为100
- 第三次迭代:a不是零,所以Result现在是100(位置*1(,位置从100更新为1000
- 第四次迭代:a为非零,结果变为100+1000=1100,位置从1000更新为10000
这里我提供了一个递归解决方案。
我还使用argv允许在命令行上进行多个输入,每个输入可以是十进制文本或十六进制文本。
我用的是字符串,而不是cin。请注意,它们都继承了相同的流输入操作。
#include <iostream>
using std::cout, std::cerr, std::endl, std::hex, std::dec;
#include <string>
using std::string;
#include <sstream>
using std::stringstream, std::istringstream;
#include <cstdint>
// typical output vvvvv v v v v v
// n: 7340032 0x700000 11100000000000000000000
// commands -- both the same input value
// ./dumy899d 7340032
// ./dumy899d 0x700000
//
// which can be mixed in the same argv list:
// ./dumy899d 7340032 0x700000
// recursion max depth: bit width of n (32 on my system)
void to_binary_R (string& retVal, int n)
{
if (0 == n) return; // recursion termination clause
to_binary_R (retVal, n/2); // (n / 2) shifts all bits of n to right
// n is on the stack and will be unchanged when the PC returns,
// thus, during 'decurse':
int a = (n % 2) + '0'; // do computation, a is 0x30 or 0x31
// int (0 or 1) 0x30 -- char is auto promoted to int
retVal += static_cast<char>(a); // append-to-retVal
// no-code-cast: 30, 31 become chars '0', '1' with cast
}
// i sometimes prefer to return a string
// (this can enable reducing cout-pollution)
string to_binary(int n)
{
string s; s.reserve(64); // declare & reserve space
to_binary_R(s, n); // fill
return s;
}
// forward declartions
// returns true when user input has '0x'
bool hexUI(const string& s);
void usage();
int main(int argc, char* argv[])
{
if (argc < 2) { usage(); return -1; }
for (int indx = 1; indx < argc; ++indx)
{
char* arg = argv[indx]; // instead of std::cin >> n;
stringstream ss(arg);
int nOrig = 0;
if (hexUI(arg)) { ss >> hex >> nOrig; }
else { ss >> dec >> nOrig; }
if (!ss.good() && !ss.eof()) // when not good state that is not
{ // caused by eof()
// notify user:
cerr << "nn ERR: ss is not good() (and not eof) "
<< "Maybe a hex parameter prefix is missing '0x'?n"
<< endl;
return -2;
}
cout << "n n: " << dec << nOrig
<< " 0x" << hex << nOrig
<< " " << to_binary(nOrig)
<< endl;
} // for (int indx = 1; indx < argc; ++indx)
return 0;
} // int main()
// returns true when user input specifies hex with '0x' prefix
bool hexUI(const string& s) { return (s.find("0x") != string::npos); }
void usage()
{
cerr << "n err: expecting 1 or more command line arguments, each argument is "
<< "n either decimal-text or hex-text (marked with '0x' prefix) "
<< "n values are displayed in decimal, binary, and hex"
<< endl;
cout << "n The following info might be different on your system:"
<< "n My development system: Linux 20.04, using g++ v9.3.0";
cout << "n sizeof(int) : "
<< sizeof(int) << " bytes " // 4 bytes
<< (sizeof(int) * 8) << " bits"; // 32 bits
cout << "n sizeof(long int) : "
<< sizeof(long int) << " bytes " // 8 bytes
<< (sizeof(long int) * 8) << " bits"; // 64 bits
// consider specifying the size, such as
cout << "n sizeof(int64_t) : "
<< sizeof(int64_t) << " bytes " // 8 bytes
<< (sizeof(int64_t) * 8) << " bits" // 64 bits
<< endl;
}
有办法解决这个问题吗?
我想到了另一个学徒,有三个步骤。
string toHex_ToBin(int n, bool slz)
{
// STEP 1: create hex encoding using stringstream and hex
stringstream ss;
ss << hex << n;
string s = ss.str();
// STEP 2: use these hex chars to append corresponding binary codes
// to empty return string
string m_s;
for (uint i = 0; i < s.size(); ++i)
{
switch (toupper(s[i]))
{
case '0': { m_s += "0000"; break; }
case '1': { m_s += "0001"; break; }
case '2': { m_s += "0010"; break; }
case '3': { m_s += "0011"; break; }
case '4': { m_s += "0100"; break; }
case '5': { m_s += "0101"; break; }
case '6': { m_s += "0110"; break; }
case '7': { m_s += "0111"; break; }
case '8': { m_s += "1000"; break; }
case '9': { m_s += "1001"; break; }
case 'A': { m_s += "1010"; break; }
case 'B': { m_s += "1011"; break; }
case 'C': { m_s += "1100"; break; }
case 'D': { m_s += "1101"; break; }
case 'E': { m_s += "1110"; break; }
case 'F': { m_s += "1111"; break; }
// default: assert(0); break;
}
// I leave this question to the reader, "would a
// vector<string> hex2bin = {"0000", "0001", .. "1111"};
// simplify this effort? "
} // for loop
// STEP 3 - if requested by user (via bool slz)
if(slz) // suppress leading zero's
{
size_t pos = m_s.find('1'); // find left most one
if (pos != std::string::npos)
m_s.erase(0, pos);
}
return m_s;
}
相关文章:
- 消除好友和成员二进制运算符的歧义
- 如何为我的类实现/重载二进制运算符
- int* 和 int[] 类型对二进制运算符 + 的操作数无效
- 类型"int"和"const char [15]"到二进制"运算符<<"的无效操作数^
- 你能帮我了解重载一元运算符和二进制运算符之间的区别吗?
- c++ 错误:二进制"运算符+"类型"矩阵*"和"矩阵*"的操作数无效
- 编译器如何区分二进制运算符和模板C++令牌>>
- 为什么我不能定义一元运算符,然后在 MSVC 的模板类中声明具有相同名称的友元二进制运算符?
- 我收到一个错误无效的操作数,类型为 const char [42] 和二进制"运算符+"的双倍数
- 类型长的长度和未解决的超载函数类型的类型的操作数与二进制运算符
- 令牌之前缺少二进制运算符 "#" 当 #define 在 #if 内时出错
- 类没有合适的复制构造函数,找不到二进制运算符 '=',
- 如何使用 Boost Spirit x3 编写具有两个后操作数语法的二进制运算符?
- 编译器将输出的流运算符<<解释为用于按位左移的二进制运算符<<
- 如何修复二进制运算符
- 类指针和类指针指向二进制运算符+的类型无效的操作数
- 铛.嵌套模板的二进制运算符重载
- 如何解决错误:在Mac上令牌"("之前缺少二进制运算符?
- CLOCKS_PER_SEC,令牌之前缺少二进制运算符.[NFIQ 2.0]
- 令牌"("错误之前缺少 QT 二进制运算符