题目如下:
给定一个数将其转换为二进制(均用字符串表示),如果这个数的小数部分不能在 32 个字符之内来精确地表示,则返回"ERROR"
。
样例
n = "3.72"
, 返回 "ERROR"
.
n = "3.5"
, 返回 "11.1"
.
解题思路:
这个题用小数乘以2取个位的常规方法显然是不明智的,二进制的拿取来源最好还是从类型上着手。拥有小数部分并能包含32位精度的类型非double莫属,但double是不支持位运算的。那么,把double所在内存copy一块即可。然而,stl内其实提供了一个很友好的容器“bitset”,这也让我们省掉转换字符的麻烦。再者,就是对 double内存分布的了解了。如图:
上图所示,double内存中指数部分,初始值为1023(01111111111),科学记数法E(10)的幂加初始值即为指数所在内存的现状。尾数部分为科学记数法小数点后的所有位,位长度不够52,其余置0。(上述的进制为二进制)。
思路实现代码如下:
void Method(char *c)
{
double d_temp = atof(c);
bitset<64> b_temp;
memcpy(&b_temp, &d_temp, 8);
string b_str = b_temp.to_string();
bitset<11> b_exp(b_str, 1, 11);
int i_exp = b_exp.to_ulong() - 1023;
for (int t = 44 + i_exp; t < b_str.size(); ++t){
if (b_str[t] == '1') {
printf("ERROR"); return;
}
}
string s_f = b_str.substr(11, i_exp + 1); s_f[0] = '1';
string s_b = b_str.substr(12 + i_exp, 32);
printf("%s%s.%s",b_str[0]=='1'?"-":"", s_f.data(), s_b.data());
}