计算浮点数中"."后面的位数?

som*_*one 4 c floating-point

这是一个面试问题.如何计算.浮点数后的数字位数.

例如,如果给出3.554输出= 3

对于43.000输出= 0.我的代码片段就在这里

double no =3.44;
int count =0;
while(no!=((int)no))
{
    count++;
    no=no*10;
}
printf("%d",count);
Run Code Online (Sandbox Code Playgroud)

有些数字无法用float类型表示.例如,没有73.487float型,由指示的数目float中c是73.486999999999995近似的.

现在如何解决它,因为它正在进行一些无限循环.

注意:在IEEE 754规范中,32位浮点数被分为24 + 7 + 1位.7位表示尾数.

R..*_*R.. 5

我怀疑这是你想要的,因为问题是要求浮点数通常没有意义的东西,但这里是答案:

int digits_after_decimal_point(double x)
{
    int i;
    for (i=0; x!=rint(x); x+=x, i++);
    return i;
}
Run Code Online (Sandbox Code Playgroud)

  • @KeithThompson:小数点后的小数位数*等于*小数点后的二进制数位数. (3认同)
  • 你在每次迭代时加倍'x`.那不会给你*二进制*数字而不是十进制数吗? (2认同)

Kei*_*son 5

如上所述,这个问题并不是真的可以解决,因为浮点数通常以二进制表示,而不是十进制。正如您所说,许多(实际上是大多数)十进制数不能完全用浮点数表示。

另一方面,所有可以用二进制浮点精确表示的数字都是具有有限位数的小数——但如果你想要 2 的结果,这不是特别有用3.44

当我运行你的代码片段时,它说3.44小数点后有 2 位数字——因为3.44 * 10.0 * 10.0恰好产生了344.0. 对于另一个数字,例如3.43(我还没有尝试过),这可能不会发生。

当我尝试使用 时1.0/3.0,它会进入无限循环。添加一些printfs 显示no恰好33333333333333324.0在 17 次迭代之后变为- 但该数字太大而无法表示为int(至少在我的系统上),并将其转换为int具有未定义的行为。

而对于大数,反复乘以 10 难免会出现浮点溢出。有一些方法可以避免这种情况,但它们并不能解决其他问题。

如果将值存储3.44double对象中,则存储的实际值(至少在我的系统上)正好是3.439999999999999946709294817992486059665679931640625,它的小数部分有 51 个十进制数字。假设你真的计算3.439999999999999946709294817992486059665679931640625. 由于3.443.439999999999999946709294817992486059665679931640625实际上是相同的 number,因此任何 C 函数都无法区分它们并知道它是否应该返回 2 或 51 (如果您的意思是 50 3.43999999999999994670929481799248605966567993164062,或者……)。

您可能会检测到存储的值“足够接近” 3.44,但这使它成为一个更加复杂的问题 - 它失去了确定 的小数部分中小数位数的能力3.439999999999999946709294817992486059665679931640625

仅当您给出的数字以某种可以实际表示小数的格式(例如字符串)存储时,或者如果您添加了一些复杂的要求来确定给定的二进制近似值要表示的十进制小数时,该问题才有意义.

通过查找在给定浮点类型中最接近的近似值是给定二进制浮点数的唯一十进制小数,可能有一种合理的方法来完成后者。