Ale*_*x B 6 c++ floating-point precision double
Double的范围超过64位整数,但其精度不如其表示(因为double也是64位,它不能适合更多的实际值).因此,当表示较大的整数时,您开始在整数部分中失去精度.
#include <boost/cstdint.hpp>
#include <limits>
template<typename T, typename TFloat>
void
maxint_to_double()
{
    T i = std::numeric_limits<T>::max();
    TFloat d = i;
    std::cout
        << std::fixed
        << i << std::endl
        << d << std::endl;
}
int
main()
{
    maxint_to_double<int, double>();
    maxint_to_double<boost::intmax_t, double>();
    maxint_to_double<int, float>();
    return 0;
}
这打印:
2147483647
2147483647.000000
9223372036854775807
9223372036854775800.000000
2147483647
2147483648.000000
注意max如何int在double不损失精度的情况下适合boost::intmax_t(并且在这种情况下为64位)不能.float甚至不能举行int.
现在,问题是:在C++中是否有一种方法可以检查给定整数类型的整个范围是否可以适应一个漏点类型而不会损失精度?
最好,
只是一个小谓词:
#include <limits>
template <typename T, typename U>
struct can_fit
{
    static const bool value = std::numeric_limits<T>::digits
                            <= std::numeric_limits<U>::digits;
};
#include <iostream>
int main(void)
{
    std::cout << std::boolalpha;
    std::cout << can_fit<short, float>::value << std::endl;
    std::cout << can_fit<int, float>::value << std::endl;
    std::cout << can_fit<int, double>::value << std::endl;
    std::cout << can_fit<long long, double>::value << std::endl;
    std::cout << can_fit<short, int>::value << std::endl;
    std::cout << can_fit<int, short>::value << std::endl;
}
测试a中是否T存在二进制精度U.适用于所有类型.
"Boostified":
// this is just stuff I use
#include <boost/type_traits/integral_constant.hpp>
template <bool B>
struct bool_type : boost::integral_constant<bool, B>
{
    static const bool value = B;
};
typedef const boost::true_type& true_tag;
typedef const boost::false_type& false_tag;
// can_fit type traits
#include <limits>
namespace detail
{
    template <typename T, typename U>
    struct can_fit
    {
        static const bool value = std::numeric_limits<T>::digits
                                <= std::numeric_limits<U>::digits;
    };
}
template <typename T, typename U>
struct can_fit : bool_type<detail::can_fit<T, U>::value>
{
    typedef T type1;
    typedef U type2;
    static const bool value = detail::can_fit<T, U>::value;
};
// test
#include <iostream>
namespace detail
{
    void foo(true_tag)
    {
        std::cout << "T fits in U" << std::endl;
    }
    void foo(false_tag)
    {
        std::cout << "T does not fit in U" << std::endl;
    }
}
// just an example
template <typename T, typename U>
void foo(void)
{
    detail::foo(can_fit<T, U>());
}
int main(void)
{
    foo<int, double>();
}
您可以std::numeric_limits<T>::digits用来知道您有多少二进制精度.例如:
int binary_digits_double = numeric_limits<double>::digits;       // 53
int binary_digits_long_long = numeric_limits<long long>::digits; // 63
int binary_digits_uint = numeric_limits<unsigned int>::digits;   // 32
| 归档时间: | 
 | 
| 查看次数: | 4436 次 | 
| 最近记录: |