C ++ 연산자의 암시 적 유형 변환 규칙
언제 캐스팅해야하는지 알고 싶습니다. 더하기, 곱하기 등을 할 때 C ++의 암시 적 유형 변환 규칙은 무엇입니까?
int + float = ?
int * float = ?
float * int = ?
int / float = ?
float / int = ?
int / int = ?
int ^ float = ?
등등...
표현이 항상 더 정확한 유형으로 평가됩니까? Java에 대한 규칙이 다릅니 까? 이 질문에 부정확하게 표현한 경우 수정하십시오.
C ++ 연산자 (POD 유형의 경우)는 항상 동일한 유형의 객체에서 작동합니다.
따라서 동일하지 않은 경우 다른 것과 일치하도록 승격됩니다.
연산 결과의 유형은 피연산자와 같습니다 (변환 후).
If either is long double the other is promoted to long double
If either is double the other is promoted to double
If either is float the other is promoted to float
If either is long long unsigned int the other is promoted to long long unsigned int
If either is long long int the other is promoted to long long int
If either is long unsigned int the other is promoted to long unsigned int
If either is long int the other is promoted to long int
If either is unsigned int the other is promoted to unsigned int
If either is int the other is promoted to int
Both operands are promoted to int
노트. 작업의 최소 크기는입니다 int
. 따라서 작업이 완료되기 전에 short
/ char
으로 승격 int
됩니다.
모든 표현식 에서 작업이 수행되기 전에 int
가로 승격됩니다 float
. 작업 결과는 float
입니다.
int + float => float + float = float
int * float => float * float = float
float * int => float * float = float
int / float => float / float = float
float / int => float / float = float
int / int = int
int ^ float => <compiler error>
의 float
결과 와 관련된 산술 연산 float
.
int + float = float
int * float = float
float * int = float
int / float = float
float / int = float
int / int = int
자세한 내용은 답변을 참조하십시오. C ++ 표준의 §5 / 9 섹션에 나와있는 내용을보십시오
산술 또는 열거 유형의 피연산자를 기대하는 많은 이진 연산자는 비슷한 방식으로 변환을 유발하고 결과 유형을 생성합니다. 목적은 결과의 유형이기도 한 공통 유형을 생성하는 것 입니다.
이 패턴을 일반적인 산술 변환이라고하며 다음과 같이 정의됩니다.
— 피연산자 중 하나가 long double 유형 인 경우 다른 피연산자는 long double로 변환됩니다.
— 그렇지 않으면 두 피연산자가 두 배인 경우 다른 피연산자가 두 배로 변환됩니다.
— Otherwise, if either operand is float, the other shall be converted to float.
— Otherwise, the integral promotions (4.5) shall be performed on both operands.54)
— Then, if either operand is unsigned long the other shall be converted to unsigned long.
— Otherwise, if one operand is a long int and the other unsigned int, then if a long int can represent all the values of an unsigned int, the unsigned int shall be converted to a long int; otherwise both operands shall be converted to unsigned long int.
— Otherwise, if either operand is long, the other shall be converted to long.
— Otherwise, if either operand is unsigned, the other shall be converted to unsigned.
[Note: otherwise, the only remaining case is that both operands are int ]
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):
This pattern is called the usual arithmetic conversions, which are defined as follows:
— If either operand is of scoped enumeration type, no conversions are performed; if the other operand does not have the same type, the expression is ill-formed.
— If either operand is of type long double, the other shall be converted to long double.
— Otherwise, if either operand is double, the other shall be converted to double.
— Otherwise, if either operand is float, the other shall be converted to float.
— Otherwise, the integral promotions shall be performed on both operands. Then the following rules shall be applied to the promoted operands:
— If both operands have the same type, no further conversion is needed.
— Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank shall be converted to the type of the operand with greater rank.
— Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.
— Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type shall be converted to the type of the operand with signed integer type.
— Otherwise, both operands shall be converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
See here for a list that's frequently updated.
This answer is directed in large part at a comment made by @RafałDowgird:
"The minimum size of operations is int." - This would be very strange (what about architectures that efficiently support char/short operations?) Is this really in the C++ spec?
Keep in mind that the C++ standard has the all-important "as-if" rule. See section 1.8: Program Execution:
3) This provision is sometimes called the "as-if" rule, because an implementation is free to disregard any requirement of the Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program.
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 minimum int
.
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 an int
and then converted to a char
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 to int
, you would get 600, which would then be implicitly down cast into an unsigned 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 from 200 + 200 + 200
to 144 + 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 in int
if the operands have a lower ranking than int
.
This is true in general of addition, subtraction, and multiplication. It is not true in general for division or modulus.
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.)
My solution to the problem got WA(wrong answer), then i changed one of int
to long long int
and it gave AC(accept). Previously, I was trying to do long long int += int * int
, and after I rectify it to long 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:
- If either operand is of type unsigned long, the other operand is converted to type unsigned long.
- If preceding condition not met, and if either operand is of type long and the other of type unsigned int, both operands are converted to type unsigned long.
- If the preceding two conditions are not met, and if either operand is of type long, t he other operand is converted to type long.
- If the preceding three conditions are not met, and if either operand is of type unsigned int, the other operand is converted to type unsigned int.
- If none of the preceding conditions are met, both operands are converted to type int.
2 . Integer conversion rules
- Integer Promotions:
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:
- No two signed integer types shall have the same rank, even if they have the same representation.
- The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.
- The rank of
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
. - The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.
- The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.
- The rank of
char
shall equal the rank ofsigned char
andunsigned char
. - The rank of any extended signed integer type relative to another extended signed integer type with the same precision is implementation-defined but still subject to the other rules for determining the integer conversion rank.
- For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 has greater rank than T3.
Usual Arithmetic Conversions:
- If both operands have the same type, no further conversion is needed.
- If both operands are of the same integer type (signed or unsigned), the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
- If the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type is converted to the type of the operand with unsigned integer type.
- If the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type is converted to the type of the operand with signed integer type.
- Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type. Specific operations can add to or modify the semantics of the usual arithmetic operations.
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
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:
int i = 3, j = 2;
double k = 33;
cout << k * j / i << endl; // prints 22
cout << j / i * k << endl; // prints 0
참고URL : https://stackoverflow.com/questions/5563000/implicit-type-conversion-rules-in-c-operators
'IT' 카테고리의 다른 글
Facebook의 새로운 iOS 앱과 같은 사이드 와이프 메뉴를 개발하는 가장 좋은 방법은 무엇입니까? (0) | 2020.06.07 |
---|---|
왜 필드 셋 태그가 필요합니까? (0) | 2020.06.07 |
배열에 shared_ptr : 사용해야합니까? (0) | 2020.06.07 |
“npm 구성 세트 레지스트리 https://registry.npmjs.org/”가 Windows bat 파일에서 작동하지 않습니다 (0) | 2020.06.06 |
왜 Console.Writeline, Console.Write가 Visual Studio Express에서 작동하지 않습니까? (0) | 2020.06.06 |