十进制转二进制C++代码问题求助:科学计数法与小数精度异常
十进制转二进制的C++代码问题修复
我需要实现十进制数转二进制的功能(比如输入9输出1001),用余数法写了如下C++代码:
#include <iostream> #include <cmath> using namespace std; int main() { float n,a = 0; int i = 0,j = 0; cin >> n; int b = n; float x = n-b; while(b > 0){ //处理整数部分 i = b%2; b = b/2; a = a + pow(10,j)*i; j++; } //保留8位小数精度 float k = 0; int m = 1; while(m <= 8){ //处理小数部分 x = x*2.0; int y = x; k = k + y/(pow(10,m)); m++; x = x - y; } cout << a + k << "\n"; }
但这段代码存在三个问题:
- 输入大数(如1111111)时,输出为
1.11111e+6,无法显示完整数字; - 小数部分精度不符合预期,例如输入9.3仅输出1001.01,达不到预设的8位小数;
- 输入53.67时,仅输出整数部分,没有小数内容。
问题原因与修复方案
1. 大数输出用科学计数法的问题
cout默认在数字长度超过阈值时切换为科学计数法输出,且用float存储转换后的二进制数会有精度丢失。建议改用字符串存储二进制结果,同时可通过输出格式设置强制禁用科学计数法:
cout << fixed << setprecision(8); //需包含<iomanip>头文件
2. 小数部分精度不足的问题
float类型的精度限制会导致低位小数丢失,pow(10,m)的计算也可能产生误差。改用字符串拼接每一位二进制小数,能精准保留8位精度,避免浮点数带来的精度损耗。
3. 输入53.67无小数输出的问题
float精度不足以精确存储53.67,导致拆分出的小数部分被判定为0。改用double类型存储原始输入和小数部分可提升精度,或者直接用字符串读取输入并拆分整数、小数部分,彻底规避浮点数精度问题。
修复后的完整代码
#include <iostream> #include <string> #include <iomanip> using namespace std; int main() { double n; cin >> n; // 处理整数部分 long long intPart = static_cast<long long>(n); string intBinary; if (intPart == 0) { intBinary = "0"; } else { while (intPart > 0) { intBinary = to_string(intPart % 2) + intBinary; intPart /= 2; } } // 处理小数部分,保留8位 double fracPart = n - static_cast<long long>(n); string fracBinary; int count = 0; while (fracPart > 1e-9 && count < 8) { // 用极小值判断是否趋近于0 fracPart *= 2; int bit = static_cast<int>(fracPart); fracBinary += to_string(bit); fracPart -= bit; count++; } // 不足8位补0 while (count < 8) { fracBinary += "0"; count++; } // 输出结果 cout << intBinary; if (!fracBinary.empty()) { cout << "." << fracBinary; } cout << endl; return 0; }
这段代码用字符串存储二进制结果,彻底解决了浮点数精度问题和科学计数法输出问题,同时保证小数部分最多8位的精度要求。
内容的提问来源于stack exchange,提问作者Observer Cosmonaut
相关产品推荐
相关产品推荐

