本来想用浮点数作为参数的,但是浮点数精度丢失造成的误差使得程序不能正常运行(比如输入参数值为1010.111时,对此值取整再用原值减整数值,1010.111-1010得到的小数部分结果赋给double型变量,变量的值变为0.1109999…),所以改用字符串作为参数。由于输出结果仍为浮点数,当转换结果的小数位数超过我格式控制的8位时,仍然会出现精度丢失的问题。
#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iomanip>
using namespace std;
class Correct
{
public:
bool operator()(char ch)
{
return (ch !='.' && ch != '1' && ch!= '0');
}
};
void myBCD(string &value)
{
//先验证是否为二进制数
vector<char> value_v;
int value_len = value.size();
//用容器存放字符串value的每个值
for(int i = 0; i < value_len; i++)
value_v.push_back(value[i]);
//查找是否有非二进制数,有则返回该值所在的迭代器,否则返回value_v.end()
vector<char>::iterator it = find_if(value_v.begin(), value_v.end(), Correct());
//查找是否有重复的小数点
int mycount = 0;
for(vector<char>::iterator vit = value_v.begin(); vit != value_v.end(); vit++)
{
if(*vit == '.')
mycount++;
}
//当有非二进制数或小数点大于1个时退出函数
if(it != value_v.end() || mycount > 1)
{
cout << "Warning: Not a binary number." << endl;
system("pause");
system("cls");
return;
}
//到此处证明没有非二进制数
int int_sum = 0;
double float_sum = 0.0;
string s_int;
string s_float;
//查找是否有小数点,有则返回小数点位置,否则返回-1
int pos = value.find(".");
int int_pos = pos;
//若小数点在第一位,则不符合数位原则
if(int_pos == 0)
{
cout << "Warning: Doesn't conform to the number principle." << endl;
system("pause");
system("cls");
return;
}
else if(int_pos == -1)
{
int_pos = value_len;
}
//取整数部分,区间为[0, int_pos)
s_int = value.substr(0, int_pos);
//获取整数部分的长度
int int_len = s_int.size();
//计算整数部分
//从右往左取数计算
for(int i = 0, j = int_len - 1; i < int_len; i++, j--)
{
char ch = s_int[j];
if(ch == '1')
int_sum += pow(2,i);
}
//当有小数时
if(pos != -1)
{
//取小数部分,区间为[pos + 1, value_len)
s_float = value.substr(pos + 1, value_len);
//获取小数部分的长度
int float_len = s_float.size();
//计算小数部分
//从左往右取数计算
for(int i = 0, j = -1; i < float_len; i++, j--)
{
char ch = s_float[i];
if(ch == '1')
float_sum += pow(2,j);
}
}
//计算完输出结果,格式控制固定输出8位小数
cout << setiosflags(ios::fixed) << setprecision(8);
cout << "result: ";
cout << value << "B = " << (double)int_sum + float_sum << "D" << endl;
cout << endl;
}
int main()
{
//测试代码
while(1)
{
string value;
cout << "value: ";
cin >> value;
myBCD(value);
}
return 0;
}