浮点提升:stroustrup vs编译器——谁是对的
floating-point promotion : stroustrup vs compiler - who is right?
在Stroustrup的新书《c++编程语言-第四版》的10.5.1节中,他说,在执行算术运算之前,使用整型提升从较短的整数类型中创建整型,类似地,使用浮点提升从浮点数中创建双精度。
我用以下代码确认了第一个索赔:
#include <iostream>
#include <typeinfo>
int main()
{
short a;
short b;
std::cout << typeid(a + b).name() << std::endl;
}
用vc++输出"int",用gcc输出"i"。
但是用float而不是short来测试它,输出仍然是"float"或"f":
#include <iostream>
#include <typeinfo>
int main()
{
float a;
float b;
std::cout << typeid(a + b).name() << std::endl;
}
根据Stroustrup,浮点提升规则没有例外,所以我希望输出"double"或"d"。
提到的关于促销的部分是错误的还是不清楚的?c++ 98和c++ 11在类型提升方面有什么不同吗?
我不知道Stroustrup的书到底说了什么,但是根据标准,在这种情况下,float
s不会转换为double
s。在应用大多数算术二进制运算符之前,先应用5p9中描述的常用算术转换:
- 如果其中一个操作数是范围枚举类型(7.2),则不执行转换;如果另一个操作数不具有相同的类型,则表达式是病态的。
- 如果其中一个操作数为长双精度类型,另一个操作数应转换为长双精度类型。
- 如果其中一个操作数为双精度,则另一个操作数转换为双精度。
- 如果其中一个操作数为浮点数,则另一个操作数转换为浮点数。
- 否则,两个操作数都要进行积分提升(4.5)。[…]
积分升序是导致两个short
s转化为int
s的原因。但是根据这些规则,两个float
不会转换为double
。如果将float
添加到double
,则float
将转换为double
。
以上代码来自c++ 11。c++ 03包含相同的规则,除了引用作用域枚举的规则。
与此同时,Stroustrup似乎认识到引用句是不正确的,或者至少是误导性的。他从10.5.1节中删除了关于浮点提升的句子。
请参阅Stroustrup网页上的第4版第3版勘误表:
pg 267: s/类似地,浮点提升用于从浮点数中创建双精度对象//
(注:表达式s/regexp/replacement/类似于sed unix工具语义。它搜索模式regexp并用replacement替换它。)
相关文章:
- VS 2017 使用交叉编译器构建 x64 项目
- 如何检测VS C++编译器是否支持C++11?
- 使用 Windows 10 和 MINGW 编译器在 VS Code 上使用 gdb 调试器进行调试时出错
- C++正则表达式失败(GCC vs Microsoft 编译器)
- VS 2017 C++编译器在 VS 2005 中找不到匹配函数
- 如何配置VS 2012的编译器来更改基本数据类型大小?
- 使用 VS 2015 的编译器警告 4456
- 模板类自动注册,vs 2017编译器删除静态成员
- VS说"Too few arguments...",但其他编译器给了我正确的输出?
- 编译器如何在向量vs Initializer_list之间做出决定
- 服务器编译器上的VS C 编译器免费许可证
- Calloc vs new 用于各种编译器中的复杂结构
- 如何在VS 2017中编译来自其他编译器的代码
- 相当于WindowsServer API for VS 2008编译器
- 尝试将 std::vector<std::p air<T, U>> 转换为其左值引用时收到 VS 编译器警告 C4239
- 如何修复与Xtime的Boost和Vs相互冲突的定义有关的编译器错误
- 如何将QT5和QT Creator 2.6.1与VS 2012中的编译器一起使用
- Eclipse CDT-输出 - 使用VS编译器时无用
- VS 编译器错误 C2752 ( "more than one partial specialization matches" ) 在 STL 中
- 是否有Visual c++编译器在线,以及如何在c++和vs简单代码之间转换