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

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

提问人: 提问时间:8/2/2022 更新时间:8/2/2022 访问量:443

问:

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

没有。std::string

所以点之后的长度是 .1234.56784

在这种情况下,您应该如何正确使用 epsilon?

我有这样的东西,一个版本有 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;
}
C++ 浮点 epsilon

评论

0赞 PaulMcKenzie 8/2/2022
两者都不能完全工作——而且它们永远不会完全工作。浮点数存储为二进制。-- 没有 std::string -- 所以这个作业是你从老师那里得到的,还是你自己编的?
0赞 Peter 8/2/2022
epsilon 的使用与此无关。 在基数 2 中具有无限表示(与 1/3 不能在有限数量的小数位中表示的原因相同,除了浮点 [通常] 在基数 2 中工作,而不是 10)。所以你的代码在不产生.更常见的做法(例如,计算输出到文本框中的用户的字符串长度)是施加一个上限(例如,如果您的代码生成 13,则将其限制为 4)。问题是,上限的选择取决于您的应用程序的需要。(这就是为什么 I/O 格式通常指定/假定数字)1234.56784
0赞 chux - Reinstate Monica 8/2/2022
user34534857,所有有限值在以十进制写入时都有精确的值。 是 0.000 大约 300 个零000222大约 790 个数字 625。让我们来看看真正的问题:为什么你想要确切的数字数?doubleDBL_MIN
0赞 chux - Reinstate Monica 8/2/2022
user34534857 代码为 a 的确切值为 1234.5677490234375。你想要那个位数(“双精度点后面的数字长度”)还是代码的位数或数字字符串中的位数还是什么?1234.5678doubledouble
0赞 Steve Summit 8/3/2022
1234.5678 点后的长度为 4不。事实并非如此。事实并非如此,因为在二进制浮点数中,没有 1234.5678 这样的数字。一开始很难考虑,但在你理解它之前,计算机浮点将仍然令人沮丧和困难。你和我使用十进制数字,如 1234.5678。但你的二进制计算机没有。

答:

3赞 Jeffrey 8/2/2022 #1

浮点数不以十进制格式存储值。它以二进制形式存储它。

例如,如果尝试存储在浮点数中,则实际可以存储的最接近的值为:234.56234.55999755859375

1234.56781234.5677490234375

(去和 https://www.h-schmidt.net/FloatConverter/IEEE754.html 一起玩,亲眼看看)

因此,浮点数中数字的长度(以十进制数字表示)定义不明确。为了保持理智,请根据大小而不是位数来定义 epsilon。