【问题标题】:c++ constant type conversion in arithmeticsc++ 算术中的常量类型转换
【发布时间】:2014-08-22 03:12:13
【问题描述】:

背景

我正在尝试在 mac 上使用 clang 学习 C++11。

问题

正如书中所说,当float类型在算术中遇到int或小写时,后者会被转换为float。在以下情况下确实如此:

cout << 9.0 / 5 << endl;

结果产生1.8000,但是当我尝试使用后缀来确保常量的类型时,例如:

cout << 9.0f / 5i << endl;

结果产生1。我想知道为什么?背后是否有不同的规则或机制?

【问题讨论】:

  • 你是怎么编译的? i 不是内置数字后缀(特别是,它并不代表 int,正如您所相信的那样)。要编译,必须在程序的某处定义operator"" i();找到它,看看它的作用。
  • 5i 是一个虚数(即复数 0 + 5i)而不是整数 5。
  • @40two 不是开箱即用的。正如 Igor 所说,编译器不知道如何处理 5i
  • @tgmath 似乎在 Clang v3.4 中,不一定是 coliru.stacked-crooked.com/a/60abcb7c6b065585
  • @IgorTandetnik 我想我误解了“我”。谢谢。但说实话,我在 test.cpp 中没有其他 operator"" i()。我只是简单地包含iostream 并直接使用该行。

标签: c++ c++11 clang clang-extensions


【解决方案1】:

使用i 作为后缀是an extension,它表示一个虚构的常量,而不是gcc 也支持的整数。如果没有警告,则启用 clang 只会将 5i 解释为复数。打开警告(特别是 -Wconversion)它会给出以下警告:

warning: imaginary constants are a GNU extension [-Wgnu-imaginary-constant]
std::cout << 9.0f / 5i << std::endl;
                    ^

warning: implicit conversion discards imaginary component: '_Complex float' to 'bool' [-Wconversion]
std::cout << 9.0f / 5i << std::endl;
~~~          ~~~~~^~~~

所以看起来_Complex 没有重载,所以结果被转换为bool。使用以下示例,我们可以更清楚地看到这一点:

float f = (9.0f / 5 + 0i) ;
std::cout << f << std::endl ;

输出1.8

如果您只想要一个 int 文字,则不需要后缀,其他整数后缀分别为 u, l, ul, ll, ullunsigned, long, unsigned long, long long and unsigned long long

所以在你的情况下:

9.0f / 5

如果您想确保 9.0 被解释为 float 将是您想要的,否则它将被解释为 double

5 也将转换为 float,因为 / 运算符将对其操作数执行通常的算术转换

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多