【问题标题】:Why are floating point types and integer types are treated differently in C++为什么浮点类型和整数类型在 C++ 中的处理方式不同
【发布时间】:2021-07-15 10:49:08
【问题描述】:

最近我发现浮点类型和整数类型在 C++ 中的处理方式完全不同。

示例 1 来自:Why are floating point types invalid template parameter types for template functions?

template <double x>
double func() {
  return x;
}

无效,而int 有效。

示例 2 来自:How to initialize private static members in C++?

class foo
{
    private:
        static float const i = 42;
};

无效,而int 有效。


在第一个链接问题中,有一个 Versuch 的答案。它指出 像 float 和 double 这样的类型在 C++ 中没有定义的实现。但是,C++ 中的许多其他地方也是如此,尤其是整数类型(1 补码与 2 补码)。

因此,浮点数和整数被区别对待是否有更深层次的原因?

【问题讨论】:

  • 只是我的两分钱:整数类型的 2 补码在 C++20 AFAIK 中成为强制性的。
  • @Scheff 很高兴知道,谢谢。

标签: c++ floating-point integer


【解决方案1】:

根本问题是12 始终具有不同的值,无论这些值如何表示。 3.1111111111153.111111111114 在不同的系统上可能有也可能没有不同的值,具体取决于值的表示方式,并且在同一系统上可能有不同的运行时值,具体取决于舍入模式的设置方式。前者是编写可移植代码的基本问题:在一个系统上,x&lt;3.111111111115&gt;x&lt;3.111111111114&gt; 可能是两种不同的类型,而在另一个系统上可能是相同的类型。后者对于类型系统来说不是问题,但会给用户设置一个陷阱,因为对这些值的相等性测试可能会从其模板实例化的类型比较中产生不同的结果。

这种不确定性的一个实际后果是

void f(x<3.111111111115>) {} 
void f(x<3.111111111114>) {}

在一个平台上可能是合法的,但在另一个平台上是非法的。

【讨论】:

  • 当我为编译器应该能够判断两个浮点是否相等(如果不是至少通过比较它们的位模式)这一事实而苦苦挣扎时,我完全忽略了我已经以某种方式告诉编译器十进制表示法的浮点值。 :-)(实际上,我可以改用十六进制数字符号,但这可能是一个蹩脚的借口——更不用说人类难以阅读了。)
  • @Scheff -- 十六进制数字表示法不能解决根本问题。不同的系统对于同一类型可以有不同的大小,因此十六进制数字不一定会产生相同的值。即使大小相同,底层表示也可能不同,因此您将谈论两个不同的浮点值。当然,如果实际值无关紧要,你可以将那些十六进制数字用作整数类型...
  • 浮点数的格式不是在编译时确定的吗?
  • @tommsch -- 是的。但不同的系统不一定使用相同的格式。十六进制表示在不同系统上不一定相同。
  • @PeteBecker 但是争论不是架构问题(“它不起作用”),而是一个:“人们可能会错误地使用它,所以我们禁止使用 id”。
猜你喜欢
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 2011-02-02
  • 2016-03-23
  • 1970-01-01
  • 2012-09-13
相关资源
最近更新 更多