C++ 中的隐式类型转换规则运营商
我想更好地知道何时应该施放。 C++ 中加法、乘法等时的隐式类型转换规则是什么。例如,
int + float = ?
int * float = ?
float * int = ?
int / float = ?
float / int = ?
int / int = ?
int ^ float = ?
等等……
表达式是否总是被计算为更精确的类型? Java 的规则是否有所不同? 如果我对这个问题的措辞不准确,请纠正我。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
在 C++ 中,运算符(对于 POD 类型)始终作用于相同类型的对象。
因此,如果它们不相同,一个将被提升以匹配另一个。
运算结果的类型与操作数相同(转换后)。
笔记。操作的最小大小为
int
。因此,在操作完成之前,short
/char
会被提升为int
。在所有表达式中,
int
在执行操作之前都会提升为float
。运算结果是一个float
。In C++ operators (for POD types) always act on objects of the same type.
Thus if they are not the same one will be promoted to match the other.
The type of the result of the operation is the same as operands (after conversion).
Note. The minimum size of operations is
int
. Soshort
/char
are promoted toint
before the operation is done.In all your expressions the
int
is promoted to afloat
before the operation is performed. The result of the operation is afloat
.涉及
float
的算术运算结果为float
。欲了解更详细的答案。看看 C++ 标准第 §5/9 节的内容
Arithmetic operations involving
float
results infloat
.For more detail answer. Look at what the section §5/9 from the C++ Standard says
由于其他答案没有讨论 C++11 中的规则,因此这里有一个。来自 C++11 标准(草案 n3337)§5/9(强调差异):
有关经常更新的列表,请参阅此处。
Since the other answers don't talk about the rules in C++11 here's one. From C++11 standard (draft n3337) §5/9 (emphasized the difference):
See here for a list that's frequently updated.
这个答案很大程度上是针对 @RafałDowgird 的评论:
请记住,C++ 标准具有最重要的“as-if”规则。请参见第 1.8 节:程序执行:
编译器无法将
int
设置为 8 位大小,即使它是最快的,因为标准要求最小int
为 16 位。因此,在理论计算机具有超快 8 位运算的情况下,算术中隐式提升到
int
可能很重要。但是,对于许多操作,您无法判断编译器实际上是否以int
的精度执行操作,然后转换为char
以存储在变量中,或者是否这些操作一直都是在 char 中完成的。例如,考虑一下
unsigned char = unsigned char + unsigned char + unsigned char
,其中加法会溢出(假设每个值均为 200)。如果您提升为int
,您将得到 600,然后它会隐式向下转换为unsigned char
,它会包装模 256,从而给出最终结果 88如果您没有进行此类促销,则必须在前两个添加之间换行,这会将问题从200 + 200 + 200
减少到144 + 200
,即 344,减少到 88。换句话说,程序不知道差异,因此如果操作数的排名较低,编译器可以自由忽略在int
中执行中间操作的命令比int
。一般的加法、减法和乘法都是如此。对于除法或模数来说,通常情况并非如此。
This answer is directed in large part at a comment made by @RafałDowgird:
Keep in mind that the C++ standard has the all-important "as-if" rule. See section 1.8: Program Execution:
The compiler cannot set an
int
to be 8 bits in size, even if it were the fastest, since the standard mandates a 16-bit minimumint
.Therefore, in the case of a theoretical computer with super-fast 8-bit operations, the implicit promotion to
int
for arithmetic could matter. However, for many operations, you cannot tell if the compiler actually did the operations in the precision of anint
and then converted to achar
to store in your variable, or if the operations were done in char all along.For example, consider
unsigned char = unsigned char + unsigned char + unsigned char
, where addition would overflow (let's assume a value of 200 for each). If you promoted toint
, you would get 600, which would then be implicitly down cast into anunsigned char
, which would wrap modulo 256, thus giving a final result of 88. If you did no such promotions,you'd have to wrap between the first two additions, which would reduce the problem from200 + 200 + 200
to144 + 200
, which is 344, which reduces to 88. In other words, the program does not know the difference, so the compiler is free to ignore the mandate to perform intermediate operations inint
if the operands have a lower ranking thanint
.This is true in general of addition, subtraction, and multiplication. It is not true in general for division or modulus.
如果排除无符号类型,则有一个有序的
层次结构:signed char、short、int、long、long long、float、
双,长双。首先,在 int 之前的任何内容
上面将被转换为 int。然后,在二元运算中,
排名较低的类型将转换为排名较高的类型,并且
结果将是较高的类型。 (你会注意到,从
层次结构,任何时候浮点数和整数类型都是
涉及到时,整型会转为浮点型
点类型。)
无符号使事情变得有点复杂:它扰乱了排名,并且
排名的部分内容由实现定义。由于
这,最好不要在同一个中混合签名和未签名
表达。 (大多数 C++ 专家似乎都避免使用 unsigned,除非
涉及到按位运算。至少,这就是
斯特鲁斯特鲁普推荐。)
If you exclude the unsigned types, there is an ordered
hierarchy: signed char, short, int, long, long long, float,
double, long double. First, anything coming before int in the
above will be converted to int. Then, in a binary operation,
the lower ranked type will be converted to the higher, and the
results will be the type of the higher. (You'll note that, from
the hierarchy, anytime a floating point and an integral type are
involved, the integral type will be converted to the floating
point type.)
Unsigned complicates things a bit: it perturbs the ranking, and
parts of the ranking become implementation defined. Because of
this, it's best to not mix signed and unsigned in the same
expression. (Most C++ experts seem to avoid unsigned unless
bitwise operations are involved. That is, at least, what
Stroustrup recommends.)
我对解决方案 439/problem/B" rel="nofollow">问题得到了WA(错误答案),然后我将
int
之一更改为long long int
,它给出了AC(接受)。之前,我尝试执行long long int += int * int
,然后将其纠正为long long int += long long int * int
。谷歌搜索我想出了,1.算术转换
类型转换的条件:
满足条件--->转换
任一操作数都是long double类型。 --->其他操作数转换为 long double 类型。
不满足前述条件,并且任一操作数的类型为double。 --->其他操作数转换为 double 类型。
不满足前述条件,并且任一操作数的类型为浮点。 --->其他操作数将转换为 float 类型。
不满足前述条件(所有操作数都不是浮点类型)。 --->对操作数执行积分提升如下:
2. 整数转换规则
当对小于 int 的整数类型执行操作时,它们会被提升。如果原始类型的所有值都可以表示为 int,则将较小类型的值转换为 int;否则,它被转换为无符号整型。整数提升作为某些参数表达式的常规算术转换的一部分应用;一元 +、- 和 ~ 运算符的操作数;和移位运算符的操作数。
整数转换排名:
long long int
的等级应大于long int
的等级,后者应大于int
的等级,它应大于short int
的等级,而short int
的等级应大于signed char
的等级。char
的等级应等于signed char
和unsigned char
的等级。常用算术转换:
My solution to the problem got WA(wrong answer), then i changed one of
int
tolong long int
and it gave AC(accept). Previously, I was trying to dolong long int += int * int
, and after I rectify it tolong long int += long long int * int
. Googling I came up with,1. Arithmetic Conversions
Conditions for Type Conversion:
Conditions Met ---> Conversion
Either operand is of type long double. ---> Other operand is converted to type long double.
Preceding condition not met and either operand is of type double. ---> Other operand is converted to type double.
Preceding conditions not met and either operand is of type float. ---> Other operand is converted to type float.
Preceding conditions not met (none of the operands are of floating types). ---> Integral promotions are performed on the operands as follows:
2 . Integer conversion rules
Integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int. Integer promotions are applied as part of the usual arithmetic conversions to certain argument expressions; operands of the unary +, -, and ~ operators; and operands of the shift operators.
Integer Conversion Rank:
long long int
shall be greater than the rank oflong int
, which shall be greater than the rank ofint
, which shall be greater than the rank ofshort int
, which shall be greater than the rank ofsigned char
.char
shall equal the rank ofsigned char
andunsigned char
.Usual Arithmetic Conversions:
整个第 4 章都在讨论转化,但我认为您应该对这些最感兴趣:
4.5 积分促销
[会议舞会]
char、signed char、unsigned char、short int 或 unsigned Short 类型的右值
如果 int 可以表示源类型的所有值,则 int 可以转换为 int 类型的右值;其他-
明智的是,源右值可以转换为 unsigned int 类型的右值。
wchar_t 类型(3.9.1)或枚举类型(7.2)的右值可以转换为第一个的右值
以下类型可以表示其基础类型的所有值:int、unsigned int、
长整型或无符号长整型。
如果 int 可以表示所有,则整型位域 (9.6) 的右值可以转换为 int 类型的右值
位字段的值;否则,如果 unsigned int 可以表示,则可以转换为 unsigned int-
重新发送位字段的所有值。如果位域仍然较大,则不会对其应用积分提升。如果
位字段具有枚举类型,出于促销目的,它被视为该类型的任何其他值。
bool 类型的右值可以转换为 int 类型的右值,其中 false 为零,true
成为一体。
这些转换称为积分促销。
4.6 浮点提升
[转换.fprom]
float 类型的右值可以转换为 double 类型的右值。该值不变。
这种转换称为浮点提升。
因此,所有涉及 float 的转换 - 结果都是 float。
只有同时涉及 int 的那个 - 结果是 int :
整数 / 整数 = 整数
Whole chapter 4 talks about conversions, but I think you should be mostly interested in these :
4.5 Integral promotions
[conv.prom]
An rvalue of type char, signed char, unsigned char, short int, or unsigned short
int can be converted to an rvalue of type int if int can represent all the values of the source type; other-
wise, the source rvalue can be converted to an rvalue of type unsigned int.
An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2) can be converted to an rvalue of the first
of the following types that can represent all the values of its underlying type: int, unsigned int,
long, or unsigned long.
An rvalue for an integral bit-field (9.6) can be converted to an rvalue of type int if int can represent all
the values of the bit-field; otherwise, it can be converted to unsigned int if unsigned int can rep-
resent all the values of the bit-field. If the bit-field is larger yet, no integral promotion applies to it. If the
bit-field has an enumerated type, it is treated as any other value of that type for promotion purposes.
An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true
becoming one.
These conversions are called integral promotions.
4.6 Floating point promotion
[conv.fpprom]
An rvalue of type float can be converted to an rvalue of type double. The value is unchanged.
This conversion is called floating point promotion.
Therefore, all conversions involving float - the result is float.
Only the one involving both int - the result is int :
int / int = int
当两个部分的类型不同时,表达式的类型将转换为两者中最大的一个。这里的问题是要了解哪一个比另一个大(它与字节大小没有任何关系)。
在涉及实数和整数的表达式中,整数将提升为实数。例如,在int + float中,表达式的类型是float。
另一个区别与类型的能力有关。例如,涉及 int 和 long int 的表达式将得到 long int 类型的结果。
The type of the expression, when not both parts are of the same type, will be converted to the biggest of both. The problem here is to understand which one is bigger than the other (it does not have anything to do with size in bytes).
In expressions in which a real number and an integer number are involved, the integer will be promoted to real number. For example, in int + float, the type of the expression is float.
The other difference are related to the capability of the type. For example, an expression involving an int and a long int will result of type long int.
注意!
转换从左到右进行。
试试这个:
Caveat!
The conversions occur from left to right.
Try this: