计算小数点后的小数位数

时间:2012-10-26 22:23:27

标签: c++ double

我想计算浮点数的小数点后的小数位数。 当实数在二进制系统中没有表示时,问题显然会增加,例如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();
}

4 个答案:

答案 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;

}