sourcecode

int가 짧고 잘린 경우 새 값은 어떻게 결정됩니까?

codebag 2023. 7. 2. 19:28
반응형

int가 짧고 잘린 경우 새 값은 어떻게 결정됩니까?

정수가 다음으로 캐스팅될 때 어떤 일이 일어나는지 누가 명확히 할 수 있습니까?short파이를 C로 요? 라즈베리 파이를 사용하고 있어요, 그래서 저는 알고 있습니다.int32비트이며, 32비트입니다.short16비트여야 합니다.

예를 들어 다음 C 코드를 사용한다고 가정합니다.

int x = 0x1248642;
short sx = (short)x;
int y = sx;

난 그걸 이해해.x누가 어떻게 정확하게 설명할 수 있을까요?시프트를 사용합니까?숫자가 정확히 어떻게 32비트에서 16비트로 잘립니까?

ISO C 표준에 따르면 정수를 서명된 유형으로 변환하고 값이 대상 유형의 범위를 벗어나면 결과가 구현 정의됩니다. (또는 구현 정의 신호를 올릴 수 있지만 이를 수행하는 컴파일러는 모릅니다.)

실제로 가장 일반적인 동작은 상위 비트가 삭제되는 것입니다.그래서 가정해보면int 및 32µ트 및short 을값변비환 16트니다입는하 합니다.0x1248642아마도 다음과 같이 보이는 비트 패턴을 생성할 것입니다.0x8642가 있는 유형(모든 에 대해 2의 하면, 은 그고거부있유형 (의의모에사 됨용서시에템스면가는하)가 됩니다.-31166.

int y   =   sx;

이는 또한 암시적 변환을 포함합니다.shortint 위이 로▁of의 범위 .int적어도 전체 범위를 포함하도록 보장됩니다.short값은 변경되지 않습니다.(당신의 예에서, 다음과 같은 가치가 있기 때문에)sx부정적으로 발생하며, 이 표현의 변화는 부호 확장, 전파를 포함할 가능성이 높습니다.1부호 비트를 결과의 16개 고차 비트에 모두 할당합니다.

제가 지적한 바와 같이, 이러한 세부 사항들은 언어 표준에 의해 요구되지 않습니다.값을 더 좁은 유형으로 잘라내려면 부호 없는 유형(언어 지정 랩어라운드 동작이 있음)과 다음과 같은 명시적 마스킹 작업을 사용하는 것이 가장 좋습니다.

unsigned int x = 0x1248642;
unsigned short sx = x & 0xFFFF;

16비트 변수에 넣을 32비트 수량이 있는 경우 값이 맞지 않을 경우 코드가 어떻게 동작할지 결정하는 것이 우선입니다.일단 그것을 결정하면, 당신은 당신이 원하는 것을 하는 C 코드를 작성하는 방법을 알아낼 수 있습니다.때때로 원하는 잘라내기 작업이 발생할 수 있습니다. 이 경우 특히 서명되지 않은 유형을 사용하는 경우 작업이 쉬워집니다.값이 범위를 벗어나는 경우 오류가 발생할 수 있습니다. 이 경우 값을 확인하고 오류를 처리할 방법을 결정해야 합니다.때때로 잘라내기보다는 값을 채우기 위해 코드를 작성해야 할 수도 있습니다.

C에서 변환이 어떻게 작동하는지 아는 것은 중요하지만, 만약 당신이 그 질문으로 시작한다면 당신은 잘못된 방향으로 당신의 문제에 접근하고 있을 것입니다.

16cm 길이의 팬에 잼을 넣으면 32cm 길이의 바나나 빵이 잘리는 것과 같은 방식으로 32비트 값이 16비트로 잘립니다.절반은 바나나빵에 맞고 나머지는 사라집니다.

CPU 레지스터에서 잘립니다.크기는 8/16/32/64비트입니다.이제 다음과 같은 레지스터를 상상할 수 있습니다.

<--rax----------------------------------------------------------------> (64-bit)
                                    <--eax----------------------------> (32-bit)
                                                      <--ax-----------> (16-bit)
                                                      <--ah--> <--al--> (8-bit high & low)
01100011 01100001 01110010 01110010 01111001 00100000 01101111 01101110

x먼저 32비트 값이 주어집니다.0x1248642메모리*에서는 다음과 같이 표시됩니다.

-----------------------------
|  01  |  24  |  86  |  42  |
-----------------------------
 31..24 23..16 15..8  7..0       

이제 컴파일러가 로드됩니다.x등기부에여기서 가장 중요하지 않은 16비트를 간단히 로드할 수 있습니다(즉,ax)에 저장합니다.sx.


*간단함을 위해 성실함이 고려되지 않음

단순히 높은 16비트는 정수에서 차단됩니다.그러므로 당신의 짧은 길이가 될 것입니다.0x8642실제로 음수입니다.-31166.

아마도 코드가 스스로 설명하도록 하라:

#include <stdio.h>

#define BYTETOBINARYPATTERN "%d%d%d%d%d%d%d%d"
#define BYTETOBINARY(byte)  \
   ((byte) & 0x80 ? 1 : 0), \
   ((byte) & 0x40 ? 1 : 0), \
   ((byte) & 0x20 ? 1 : 0), \
   ((byte) & 0x10 ? 1 : 0), \
   ((byte) & 0x08 ? 1 : 0), \
   ((byte) & 0x04 ? 1 : 0), \
   ((byte) & 0x02 ? 1 : 0), \
   ((byte) & 0x01 ? 1 : 0) 

int main()
{
    int x    =   0x1248642;
    short sx = (short) x;
    int y    =   sx;

    printf("%d\n", x);
    printf("%hu\n", sx);
    printf("%d\n", y);

    printf("x: "BYTETOBINARYPATTERN" "BYTETOBINARYPATTERN" "BYTETOBINARYPATTERN" "BYTETOBINARYPATTERN"\n",
        BYTETOBINARY(x>>24), BYTETOBINARY(x>>16), BYTETOBINARY(x>>8), BYTETOBINARY(x));

    printf("sx: "BYTETOBINARYPATTERN" "BYTETOBINARYPATTERN"\n",
        BYTETOBINARY(y>>8), BYTETOBINARY(y));

    printf("y: "BYTETOBINARYPATTERN" "BYTETOBINARYPATTERN" "BYTETOBINARYPATTERN" "BYTETOBINARYPATTERN"\n",
        BYTETOBINARY(y>>24), BYTETOBINARY(y>>16), BYTETOBINARY(y>>8), BYTETOBINARY(y));

    return 0;
}

출력:

19170882
34370
-31166

x: 00000001 00100100 10000110 01000010
sx: 10000110 01000010
y: 11111111 11111111 10000110 01000010

당신이 볼 수 있듯이.int->short예상대로 하위 16비트를 산출합니다.

캐스팅short로.int을 산출합니다.short16개의 하이 비트가 설정된 상태에서.하지만, 저는 이것이 구현에 특정적이고 정의되지 않은 행동이라고 생각합니다.당신은 기본적으로 16비트의 메모리를 정수로 해석합니다. 이는 발생하는 모든 쓰레기 중 16비트를 추가로 읽습니다(또는 컴파일러가 좋고 버그를 더 빨리 찾도록 돕기를 원하는 경우 1비트).

다음을 수행하는 것이 안전해야 한다고 생각합니다.

int y = 0x0000FFFF & sx;

분명히 잃어버린 비트를 되찾을 수는 없겠지만, 이것은 높은 비트가 적절하게 영점화되도록 보장할 것입니다.

만약 누군가가 권위 있는 참조로 짧은 -> int highbit 동작을 검증할 수 있다면, 그것은 감사합니다.

참고: 이 답변에서 채택된 이진 매크로입니다.

sx값은 최하위 2바이트와 동일합니다.x이 경우 0x8642가 되며(16비트 부호 정수로 해석되는 경우) 10진수로 -31166이 됩니다.

언급URL : https://stackoverflow.com/questions/34885966/when-an-int-is-cast-to-a-short-and-truncated-how-is-the-new-value-determined

반응형