十进制转二进制C++程序输出异常求助:结果不符合预期
问题排查与修正
1. 核心问题1:pow()函数的精度误差
你代码里用pow(10, i)计算位权重,这是浮点数运算,会出现精度丢失。比如pow(10,2)实际返回的可能是99.9999999999,转成整数时被截断为99,直接导致结果错误:
- 输入4时,正确二进制是
100,但计算时最高位的1乘以99,加前面的0,得到99; - 输入5时,最高位的1乘以99加前面的1,得到
100(而非正确的101)。
解决方法:用整数变量维护权重,完全避免浮点数运算:
int decitobin(int n){ int ans=0; int weight=1; // 初始为10^0=1 while(n!=0){ int bit=n&1; ans += bit * weight; weight *=10; n=n>>1; } return ans; }
2. 核心问题2:负数补码的计算逻辑完全错误
你对十进制形式的二进制数执行~newans按位取反,这完全搞错了补码的计算方式:
~是对int类型的所有二进制位(通常32位)取反,而非针对你得到的十进制数的每一位二进制数字。比如110(对应十进制6)作为int是0x6,按位取反后是0xFFFFFFF9,加1得到0xFFFFFFFA,对应十进制-6,这和你预期的补码输出完全不符;- 用十进制数存储二进制位的方式,无法保留补码所需的固定位数(比如32位)和前导零,也无法正确处理符号位。
解决方法:如果要输出负数的补码,建议用字符串来构建二进制结果,这样能准确处理每一位:
#include<iostream> #include<string> #include<algorithm> // 用于reverse函数 using namespace std; string decitobin(int n){ string ans; if(n == 0){ return "0"; } bool isNegative = false; // 处理负数,注意:如果n是INT_MIN,-n会溢出,这里假设输入不是INT_MIN if(n < 0){ isNegative = true; n = -n; } // 提取每一位二进制(从低位到高位) while(n != 0){ ans += (n & 1) ? '1' : '0'; n = n >> 1; } if(isNegative){ // 补零到32位(标准int的位数) while(ans.size() < 32){ ans += '0'; } // 取反每一位 for(char &c : ans){ c = (c == '1') ? '0' : '1'; } // 加1处理进位 int carry = 1; for(int i=0; i<ans.size() && carry; i++){ int digit = ans[i] - '0'; digit += carry; carry = digit / 2; ans[i] = (digit % 2) + '0'; } } // 反转得到正确的高位到低位顺序 reverse(ans.begin(), ans.end()); return ans; } int main(){ int n; cin>>n; cout<<decitobin(n)<<endl; }
测试结果
- 输入5:输出
101(正确) - 输入4:输出
100(正确) - 输入-6:输出
11111111111111111111111111111010(32位补码,正确)
内容的提问来源于stack exchange,提问作者Navneet Singh
相关产品推荐
相关产品推荐

