简体   繁体   English

C++ - 如何计算双精度/浮点数中点后数字的长度?

[英]C++ - How to count the length of the digits after the dot in a double / float?

How to count the length of the digits after the dot in a double / float?如何计算双/浮点中点后数字的长度?

Without std::string .没有std::string

So the length after the dot of 1234.5678 is 4 .所以1234.5678点之后的长度是4

And how should you correctly use epsilon in such a situation?在这种情况下,您应该如何正确使用 epsilon?

I have something like this, one version with epsilon and another without, neither work fully.我有这样的东西,一个带有 epsilon 的版本,另一个没有,都不能完全工作。

// Version 1.
template <typename T> inline constexpr
unsigned int get_length(T x, const bool& include_dot = false) {
    unsigned int len = 0;
    x = abs(x);
    auto c = x - floor(x);
    T factor = 10;
    T eps = epsilon() * c;
    while (c > eps && c < 1 - eps) {
        c = x * factor;
        c = c - floor(c);
        factor *= 10;
        eps = epsilon() * x * factor;
        ++len;
    }
    if (include_dot && len > 0) { ++len; }
    return len;
}

// Version 2.
template <typename T> inline constexpr
unsigned int get_length(const T& x, const bool& include_dot = false, const unsigned int& max_consequtive_zeros = 6) {
    unsigned int len = 0;
    unsigned int zero_count = 0;
    short digit;
    auto decimals = get_decimals(x);
    while (decimals != 0 && len < 14) {
        decimals *= 10;
        digit = decimals;
        if (digit == 0) {
            if (zero_count >= max_consequtive_zeros) { break; }
            ++zero_count;
        }
        else { zero_count = 0; }
        decimals -= digit;
        ++len;
        // std::cout << len << ": " << decimals << " zeros: " << zero_count << "\n";
    }
    if (include_dot && len > 0) { ++len; }
    return len - zero_count;
}

A floating point number doesn't store a value in decimal format.浮点数不以十进制格式存储值。 It stores it in binary.它以二进制形式存储它。

For example, if you try to store 234.56 in a float, the closest value that can actually be stored is: 234.55999755859375例如,如果您尝试将234.56存储在浮点数中,则实际可以存储的最接近的值是: 234.55999755859375

1234.5678 is 1234.5677490234375 1234.56781234.5677490234375

(go play with https://www.h-schmidt.net/FloatConverter/IEEE754.html to see for yourself) (去玩https://www.h-schmidt.net/FloatConverter/IEEE754.html自己看看)

As such, the length (in decimal digits) of a number in a float is ill-defined.因此,浮点数的长度(十进制数字)是不明确的。 To keep your sanity, please define an epsilon based on the magnitude, not on the number of digits.为了保持理智,请根据大小而不是位数来定义 epsilon。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM