计算没有库的浮点值的小数位数?

1 c++ floating-point count digits

我需要计算浮点值的小数位数,例如

1234. 567 - > 3
2. 1233 - > 4
4. 2432 - > 4

我最初的想法是:

number = 1234.567;  
...  
while (number - (int)number > 0.0)  
{  
  // Count decimal places  
  ...  
  number *= 10;  
}
Run Code Online (Sandbox Code Playgroud)

但是,这会导致while条件下的浮点精度问题.唯一安全的解决方法是从float转换为字符串,然后执行基于字符串的小数位数计数.

问题是:我不得使用任何库,无论是第三方还是C++标准库(由于环境限制).我知道如何在char*上操作,但是如何在不使用C++库的情况下将我的float值转换为字符串(即char*)?

任何帮助是极大的赞赏.


//编辑:这是我目前的方法,但仍然不起作用(例如对于2.55555).如何选择合适的阈值?

float abs(float number)  
{  
  return (number > 0.0 ? number : number * -1);  
}  

int round(float number)  
{  
  return (int)(number + 0.5);  
}  

void splitFloat(float* number, int* mantissa, int* exponent)  
{  
  while (abs(*number - round(*number)) > 0.00001)  
  {  
    // *number -= (int)*number; // ???  
    *number *= 10.0;  

    *mantissa = *number;  
    *exponent += 1;  

    cout << "Number: " << *number << ", Mantisse: " << *mantissa << ", Exponent: " << *exponent << endl;  
  }  
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*som 5

你最初的想法非常接近,问题是浮点会进行舍入,从而使结果不准确.您需要使用阈值而不是精确地比较0.0,并且您需要允许(int)操作可能错误地截断,而您应该舍入.您可以在截断前添加0.5来舍入.

当数字位数不再适合时,您也会遇到问题int.您可以通过在每一步中减去数字的整数部分来提供帮助.

编辑:要选择适当的阈值,请选择要处理的最大小数位数.如果是4,那么您要输出的最小数字是0.0001.使你的门槛降低一半,或0.00005.现在,每次将数字乘以10,也要将阈值乘以10!

float threshold = 0.00005;
while (abs(*number - round(*number)) > threshold)  
{  
  *number *= 10.0;
  threshold *= 10.0;
  // ...
}
Run Code Online (Sandbox Code Playgroud)

如果你的float和int都是32位,你不必担心减去int.当你正在做的时候,它会更难以返回尾数.

此外,我曾打算给你一个警告,但忘了:这只适用于正数.

还有一个警告,a的值范围float非常有限.1234.5670例如,您可能无法准确表示,并且最终会得到一个无关数字.改变以double解决这个问题.