如何查看传入的浮点数的大小?

How to see the size of the incoming floating point number?

用户向输入写入一个数字,它存储在一个字符串中。我如何检查此数字是否包含在 float 类型的大小中,或者它是否需要 double?

除非您的浮点数很大或非常小,即超出 -3.4E38 到 3.4E38 的范围,否则浮点数 32 将存储您在大小而非准确性方面扔给它的任何内容。因此,真正的问题是您需要多少有效数字才能最大程度地减少舍入误差。我推荐你阅读 https://www.itu.dk/~sestoft/bachelor/IEEE754_article.pdf

如果您不受磁盘 space 或内存的限制,那么只需使用 float 64。

此答案仅适用于正浮点数,但可能对您有所帮助:

IEEE 754定义的32位浮点数(8字节/单精度)具有3.40282 x 10^38的最大正数float,最小的正数float号码是 1.17549 x 10^-38.

使用strtod()将字符串中的数字转换为double。这是必需的,因为您实际上不知道数字是否已经 double

然后检查数字是否在上面提供的范围内。

如果是,分配一个float。如果没有,继续使用double对象。

这种方式有点泥泞,因为你已经分配了一个double,然后选择是使用之前用作缓冲区的double还是分配另一个float。尽管如此,如果您根据字符串的数量分配例如一个数组,这将是有益的。此外,您还可以选择动态分配缓冲区 double 对象并在使用后 free() 它。


一种更简单的方法是从一开始就选择 double。所以确保这个过程确实是必需的。除非明确禁止使用 double,否则只需使用 double.

这将为您节省大量时间和精力,也是最安全的方式。

How can I check if this number is included in size in the float type or does it need a double?

编码为字符串的数字提供了无限的可能性。有限floatdouble范围精度

请注意 floatdouble 的子集。

The set of values of the type float is a subset of the set of values of the type double; C17dr § 6.2.5 10

范围

double 的范围通常远远超过 float 的范围。

精度

典型的floatdouble是一个2N*一个dyadic rational:一些integer/some-power-of-two。因此,从 string 到浮点数的转换涉及一些舍入。例如。 0.1 通常不会 完全 表示为 float 也不会表示为 double.

这意味着大多数不精确的转换,即使在 float 范围内,也会有更接近 double 的答案而不是 float


为了达到 OP 的目标,我建议将字符串转换为两者并测试转换结果。

int float_or_double_range(const char *s) {
  char *endptr;
  errno = 0;
  double d = strtod(s, &endptr);
  if (s == endptr) return 'n';  // Neither
  if (errno == ERANGE) return 'd';

  errno = 0;
  double f = strtof(s, &endptr);
  if (s == endptr) return 'd';
  if (errno == ERANGE) return 'd';

  if (d == f) return 'f'; // encodable as float and double
  return 'd';
}

备注:

回想一下,FP strto...() 函数的正确性受实施质量问题的影响,它们本身可能无法在所有情况下提供最佳答案。

要查找转换后的字符串值是否与 doublefloat 相同,我建议不要将 字符串 转换为 double 然后 doublefloat。这涉及 double rounding 并在极端情况下引入错误。