잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).

여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.

감사합니다. -현록

후원해주실 분은 여기로→

현록의 기록저장소

기본자료형(primitive type)간 연산의 암시적 캐스팅 본문

Study/C

기본자료형(primitive type)간 연산의 암시적 캐스팅

현록 2020. 1. 14. 22:18

https://en.cppreference.com/w/c/language/conversion

C 표준의 설명 중 일부의 원문과 해석을 적어둠.

 

 


Usual arithmetic conversions

The arguments of the following arithmetic operators undergo implicit conversions for the purpose of obtaining the common real type, which is the type in which the calculation is performed:

1) If one operand is long double, long double complex, or long double imaginary, the other operand is implicitly converted as follows:

  • integer or real floating type to long double
  • complex type to long double complex
  • imaginary type to long double imaginary

2) Otherwise, if one operand is double, double complex, or double imaginary, the other operand is implicitly converted as follows:

  • integer or real floating type to double
  • complex type to double complex
  • imaginary type to double imaginary

3) Otherwise, if one operand is float, float complex, or float imaginary, the other operand is implicitly converted as follows:

  • integer type to float (the only real type possible is float, which remains as-is)
  • complex type remains float complex
  • imaginary type remains float imaginary

 

 

※ conversion rank: long double > double > float > int

 


 

4) Otherwise, both operands are integers. Both operands undergo integer promotions (see below); then, after integer promotion, one of the following cases applies:

  • If the types are the same, that type is the common type.
  • Otherwise (the types are not the same): If the types have the same signedness (both signed or both unsigned), the operand whose type has the lesser conversion rank (see below) is implicitly converted to the other type.
  • Otherwise (the signedness is different): If the unsigned type has conversion rank greater than or equal to the rank of the signed type, then the operand with the signed type is implicitly converted to the unsigned type.
  • Otherwise (the signedness is different, and the unsigned type has conversion rank less than the signed type): If the signed type can represent all values of the unsigned type, then the operand with the unsigned type is implicitly converted to the signed type.
  • Otherwise: Both operands undergo implicit conversion to the unsigned type counterpart of the signed operand's type.
1.f + 20000001; // int is converted to float, giving 20000000.00
                // addition and then rounding to float gives 20000000.00
(char)'a' + 1L; // First, char is promoted back to int.
                // this is signed + signed case, different rank
                // int is converted to long, the result is 98 signed long
2u - 10; // signed / unsigned, same rank
         // 10 is converted to unsigned, unsigned math is modulo UINT_MAX+1
         // for 32 bit ints, result is 4294967288 of type unsigned int (aka UINT_MAX-7)
0UL - 1LL; // signed/unsigned diff rank, rank of signed is greater.
           // If sizeof(long) == sizeof(long long), signed cannot represent all unsigned
           // this is the last case: both operands are converted to unsigned long long
           // the result is 18446744073709551615 (ULLONG_MAX) of type unsigned long long

 

if-if else문처럼, 아래로 가면서 else if.

 

1. 자료형이 같다: 그냥 진행

 

2. (자료형이 다르다) && (둘 다 unsigned || 둘 다 signed)

 (즉, 부호유무는 신경 쓸 필요없는 경우임. 둘 다 부호유무가 같으니까.)

 :자료형의 conversion rank가 낮은 type이, 높은 type으로 변환.

 → 즉, 일반적인 conversion을 따름.

 

3. (unsigned와 signed의 만남) && (unsigned 쪽의 conversion rank가 같거나 높다)

 (같다는 것은 같은 자료형을 포함. e.g., int + unsigned int)

 : unsigned 쪽의 type이 된다.

 → unsigned 쪽 자료형

 

4. (unsigned와 signed의 만남) && (unsigned 쪽의 conversion rank가 낮다) && (signed 쪽의 표현범위가 unsigned 쪽의 표현범위(부호없는의 넓은범위) 전체를 표현할 수 있다)

 : signed 쪽의 type이 된다.

 → signed 쪽 자료형

 

5. 그 외

 : signed 쪽의 type이 되지만, 부호유무는 unsigned가 된다.

 → unsigned(signed 쪽 자료형)

 


 

The result type is determined as follows:

  • if both operands are complex, the result type is complex
  • if both operands are imaginary, the result type is imaginary
  • if both operands are real, the result type is real
  • if the two floating-point operands have different type domains (complex vs. real, complex vs imaginary, or imaginary vs. real), the result type is complex
double complex z = 1 + 2*I;
double f = 3.0;
z + f; // z remains as-is, f is converted to double, the result is double complex

As always, the result of a floating-point operator may have greater range and precision than is indicated by its type (see FLT_EVAL_METHOD).

Note: real and imaginary operands are not implicitly converted to complex because doing so would require extra computation, while producing undesirable results in certain cases involving infinities, NaNs and signed zeros. For example, if reals were converted to complex, 2.0×(3.0+i∞) would evaluate as (2.0+i0.0)×(3.0+i∞) ⇒ (2.0×3.0–0.0×∞) + i(2.0×∞+0.0×3.0) ⇒ NaN+i∞ rather than the correct 6.0+i∞. If imaginaries were converted to complex, i2.0×(∞+i3.0) would evaluate as (0.0+i2.0) × (∞+i3.0) ⇒ (0.0×∞ – 2.0×3.0) + i(0.0×3.0 + 2.0×∞) ⇒ NaN + i∞ instead of –6.0 + i∞.

Note: regardless of usual arithmetic conversions, the calculation may always be performed in a narrower type than specified by these rules under the as-if rule

 

 

 


더 다양한 conversion rule은 원문을 참고.

 

 

'Study > C' 카테고리의 다른 글

POCU 성적표  (0) 2020.04.30
Comments

잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).

여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.

감사합니다. -현록

후원해주실 분은 여기로→