将浮点数拆分为小数和整数部分

时间:2012-07-04 09:10:31

标签: c++

我正在编写一个模板类,旨在使用任何浮点类型。对于某些方法,我需要将数字拆分为其整数和小数部分。对于原始浮点类型,我可以强制转换为整数来截断小数部分,但这不适用于大数字类。理想情况下,我的班级只会在计算中使用四种基本算术运算(加法,减法,乘法,除法)。

以下方法是我提出的解决方案。所有这一切都是减去10的幂,直到原始数小于1.它运作良好,但似乎是一种蛮力的方法。有没有更有效的方法来做到这一点?

template< typename T >
class Math
{
    public:

    static T modf( T const & x, T & intpart )
    {
        T sub = 1;
        T ret = x;

        while( x >= sub )
        {
            sub *= 10;
        }

        sub /= 10;

        while( sub >= 1 )
        {
            while( ret >= sub )
            {
                ret -= sub;
            }

            sub /= 10;

        }//while [sub] > 0

        intpart = x - ret;

        return ret;
    }
}

请注意,为简洁起见,我删除了签名管理代码。

3 个答案:

答案 0 :(得分:2)

您可以用二分搜索替换减法循环,尽管这不是复杂性类的改进。

你所需要的数量大约等于x的十进制数之和,而二进制搜索需要大量等于3的加法和除以2的运算。和 - 一位乘以x的小数位数。

通过你正在做的事情以及二进制搜索,在寻找上限时没有特别的理由使用10的幂,你可以使用任何数字。其他一些数字平均可能会快一些,但可能取决于类型T

顺便说一句,我也很想在modf(或命名空间中的免费模板函数)中使Math成为函数模板,而不是Math类模板。这样,您可以为特定类型(尤其是内置类型)一次特化或重载一个函数,而无需专门化整个Math

示例:

namespace Math
{
    template <typename T>
    T modf( T const & x, T & intpart )
    { ... }
}

这样称呼:

float f = 1.5, fint;
std::cout << Math::modf(f, fint) << '\n';

double d = 2.5, dint;
std::cout << Math::modf(d, dint) << '\n';

mpf_class ff(3.5), ffint(0);  // GNU multi-precision
std::cout << Math::modf(ff, ffint) << '\n';

像这样重载:

namespace Math {
    double modf(double x, double &intpart) {
        return std::modf(x, &intpart);
    }

    mpf_class modf(const mpf_class &x, mpf_class &intpart) {
        intpart = floor(x);
        return x - intpart;
    }
}

答案 1 :(得分:0)

使用std :: modf mb更好吗? 对于自定义类型,您可以释放Math类专业化。

#include <cmath>
#include <iostream>

template<typename T>
class Math
{
public:
    static T modf(const T& x, T& integral_part)
    {
        return std::modf(x, &integral_part);
    }
};

int main()
{
    double d_part = 0.;
    double res = Math<double>::modf(5.2123, d_part);
    std::cout << d_part << " " << res << std::endl;
}

答案 2 :(得分:0)

我不知道你的“理想上只使用数学运算”的限制是多么严格,但是对于小数部分,你能将它提取到字符串并转换回浮点数吗?