如何计算双精度/浮点C中的位数

新手上路,请多包涵

我正在尝试计算 double 的小数部分的位数,但是出了点问题,我得到了无限循环:

 double pi = 3.141592;
int counter = 0;
for (; pi != int(pi); ++counter)
    pi *= 10;
cout << counter << endl;

我刚刚读到这个问题,但是我找不到一个好的解决方案。真的没有比将数字转换为字符串并计数字符更好的方法吗?我想还有更正确的方法。

原文由 hant0508 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 618
2 个回答

计算机中的浮点数使用二进制(以 2 为底,零和一,就像计算机中的几乎所有数字一样)。所以它们中有一个确切数量的二进制数字,更多的是 double 而更少的是 float 。但是,如果您将像 3.141592 这样的十进制常量转换为 double ,然后完全准确地打印它,您不会得到相同的数字。这是因为在基数之间转换小数通常并不精确(它与 13 具有无限小数扩展 0.33 时获得的类似效果…)。例子:

 double pi = 3.141592;
std::cout << std::setprecision(100) << pi << std::endl;

我的输出:

 3.14159200000000016217427400988526642322540283203125


因此,当您在问题代码中开始将其乘以 10 时,您可以看到它在很长一段时间内都不会变成一个精确的整数(到那时它已经远远超出了 int 的范围),所以你的条件永远不会为真(要么有小数部分,要么双精度数太大而无法放入整数)。

换句话说,您所问的,直接从 double 计算数字是没有意义的。您首先需要将其打印为字符串,否则您实际上 没有 多少十进制数字可以计算。当然,您可以对此进行微优化并跳过实际转换为 ASCII 或 UTF-16 字符串,但我不认为这是值得麻烦的情况(可能作为学习练习除外)。

如果您在计算中需要精确的十进制数字,则需要一种特殊的数字类型,它不会以二进制形式存储分数。这种数字类型的示例是 Java BigDecimal

原文由 hyde 发布,翻译遵循 CC BY-SA 3.0 许可协议

num = pi - int(pi);
while abs(num) >= 0.0000001{
    num = num * 10;
    count = count + 1;
    num = num - int(num);
}
cout<< count<< endl;

有关更多信息,您可以阅读此 C/C++ 计算小数位数? .

原文由 Qingfu Wen 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题