我想计算浮点数的小数点后的小数位数。
当实数在二进制系统中没有表示时,问题显然会增加,例如3.5689113
。
我在想 - 如果有人在源代码中写这个真实的 - 如果有可能得到数字7即小数点后的位数
例如,天真的以下代码不起作用:
int main()
{
double num = 3.5689113;
int count = 0;
num = abs(num);
num = num - int(num);
while ( abs(num) >
0.0000001 )
{
num = num * 10;
count = count + 1;
num = num - int(num);
}
std::cout << count; //48
std::cin.ignore();
}
答案 0 :(得分:3)
当这样的东西不起作用时,你会尝试打印数字。
我这样做了here,我发现你有一些浮动数精度问题。
我将int
四舍五入改为ceil
四舍五入,它就像一个魅力。
尝试将int
放回去,你会看到:)
编辑:比使用ceil
更好的策略(可能会产生相同的舍入问题)是将数字四舍五入到最接近的整数。您可以使用floor(myNumber+0.5)
。
这是修改后的代码
int main()
{
double num = 3.56891132326923333;
// Limit to 7 digits
num = floor(num*10000000 + 0.5)/10000000;
int count = 0;
num = abs(num);
num = num - floor(num+0.5);
while ( abs(num) >
0.0000001 )
{
cout << num << endl;
num = num * 10;
count = count + 1;
num = num - floor(num+0.5);
}
std::cout << count; //48
std::cin.ignore();
return 0;
}
答案 1 :(得分:3)
为防止浮点近似引入的错误,请尽早将数字转换为整数并使用该数字。
double num = 3.5689113;
int count = 7; // a maximum of 7 places
num = abs(num);
int remainder = int(0.5 + 10000000 * (num - int(num)));
while ( remainder % 10 == 0 )
{
remainder = remainder / 10;
--count;
}
答案 2 :(得分:1)
对于浮点类型T
,您最多可以恢复std::numeric_limits<T>::digits10
个数字。因此,要确定最后一个非零小数位的位置,您可以将此值用作精度并格式化数字。要使用指数表示法避免输出,您需要将格式标记设置为std::ios_base::fixed
并考虑非小数位数:
std::ostringstream out;
int non_fraction(std::abs(value) < std::numeric_limits<double>::epsilon()
? 1: (1 + std::log(std::abs(value)) / std::log(10)));
out << std::setprecision(std::numeric_limits<double>::digits10 - non_fraction)
<< std::fixed
<< value;
如果有一个小数点,你只需要计算直到零的尾随序列的位数。
答案 3 :(得分:0)
我建议转换为一个字符串,然后循环遍历它并计算在你达到句号后出现的字符数。下面是一个示例(可能需要一些小修补,因为我已经用C ++完成了这一步);
bool passedRadix = false
int i = 0; // for counting decimals
std::ostringstream strs;
strs << dbl; // dbl is 3.415 or whatever you're counting
std::string str = strs.str();
for(char& c : str) {
if (passedRadix == true)
i++;
if (c == '.')
passedRadix = true;
}