C++实现十进制整数二进制补数:代码错误排查求助
二进制位翻转错误排查与修正
需求
给定十进制整数,翻转其二进制形式的每一位(0变1,1变0),将翻转后的二进制数转回十进制并输出。示例:输入n=5(二进制101),翻转后为010,对应十进制2。
原代码
#include <iostream> #include<math.h> using namespace std; int main(){ int n; cin>>n; int ans=0; int a2ns=0; int finalans=0; int k=0; int i=0; int j=0; while(n!=0){ int bit = n&1; ans = bit*pow(10,i)+ans; i++; n=n>>1; } cout<<ans<<endl; while(ans!=0){ int digit = ans&1; if(digit==0){ digit =1; } else{ digit =0; } a2ns = digit*pow(10,i)+a2ns; j++; ans = ans>>1; } cout<<a2ns<<endl; while(a2ns!=0){ int digit1 = a2ns%10; if(digit1==1){ finalans = finalans + pow(2,k); } a2ns=a2ns/10; k++; } cout<<finalans; }
输出对比
- 实际输出:
235 11101011 1199999995 768 - 预期输出:
235 11101011 00010100 20
错误原因
- 指数使用错误:第二个循环中计算
a2ns时,误用了第一个循环结束后的总位数i作为pow(10, i)的指数,而非当前位的索引j。这会导致每一位都被放大到10^i级别,直接超出int类型的存储范围,产生溢出错误。 - 二进制位处理逻辑冗余且易出错:通过十进制整数存储二进制位的方式既容易溢出,又无法保留原二进制的位数(比如原数的二进制前导0会丢失,导致翻转后的结果位数不足)。
- 位提取方式逻辑混淆:第二个循环中用
ans&1提取二进制位,虽然在数值上巧合正确,但逻辑上是错误的——ans是存储二进制位的十进制整数,应该用ans%10提取每一位的二进制值。
修正代码
以下是简化且正确的实现,直接操作二进制位,避免中间十进制存储的冗余步骤:
#include <iostream> #include <cmath> using namespace std; int main(){ int n; cin >> n; // 1. 输出原数的二进制形式(转为十进制整数格式,与原代码一致) int originalBinaryNum = 0; int temp = n; int bitCount = 0; while(temp != 0){ int bit = temp & 1; originalBinaryNum = bit * pow(10, bitCount) + originalBinaryNum; bitCount++; temp >>= 1; } cout << originalBinaryNum << endl; cout << originalBinaryNum << endl; // 2. 输出翻转后的二进制字符串(保留原位数) string flippedBinaryStr; for(int pos = bitCount - 1; pos >= 0; pos--){ int originalBit = (n >> pos) & 1; flippedBinaryStr += (1 - originalBit) ? '1' : '0'; } cout << flippedBinaryStr << endl; // 3. 计算翻转后的十进制值 int flippedDecimal = 0; for(int pos = 0; pos < bitCount; pos++){ int originalBit = (n >> pos) & 1; if(1 - originalBit == 1){ flippedDecimal += pow(2, pos); } } cout << flippedDecimal << endl; return 0; }
关键修正点
- 直接通过位运算提取原数的每一位二进制位,避免中间十进制存储的溢出问题。
- 保留原二进制的位数,确保翻转后的结果位数与原数一致(包括前导0的翻转)。
- 分别处理二进制字符串输出和十进制值计算,逻辑清晰,避免混淆。
内容的提问来源于stack exchange,提问作者Harshvardhan Singh
相关产品推荐
相关产品推荐

