내적 강인함을 길러라 [메모리의 데이터 저장에 대한 심층 분석]

메모리에 데이터 저장

성형수술

다시 시작하기 전에 약간의 예비 지식, 즉 원래 코드는 역 코드와 보완 코드가 무엇인지 알아 봅시다.

원래 코드

양수와 음수의 형태로 값을 이진수로 직접 변환하여 원래 코드를 얻을 수 있습니다.

역코드

원래 코드의 부호 비트를 변경하지 않고 다른 비트를 차례로 반전하여 역 코드를 얻습니다.

보어

역 코드 + 1은 보완 코드를 얻습니다.


위의 예표를 통해 컴퓨터 메모리에서 다음 단계로 진행할 수 있습니다.

컴퓨터의 정수에 대한 세 가지 이진 표현 방법, 즉 원본 코드, 보완 코드 및 보완 코드가 있습니다.
세 가지 표현 방법은 모두 부호 비트와 값 비트의 두 부분으로 구성되며 부호 비트는 0을 사용하여 "양수"를 나타내고 1을 사용하여 "음수"를 나타냅니다
.
음의 정수를 나타내는 방법에는 세 가지가 있습니다.

정수 메모리에 저장되는 이진수는 2의 보수 인데 왜 2의 보수일까요?

컴퓨터 시스템에서 값은 항상 2의 보수로 표현되고 저장됩니다. 그 이유는 보수 코드를 사용하면 부호 비트와 값 필드를
균일하게 처리
할 수 있는 동시에 덧셈과 뺄셈도 균일하게 처리할 수 있기 때문입니다(CPU에는 가산기만 있음). 와 원본 코드가 서로 변환되며 작동 프로세스는
동일하며 추가 하드웨어 회로가 필요하지 않습니다.

1-1
1+-1//因为CPU只有加法器
00000000000000000000000000000001//1的原码
10000000000000000000000000000001//-1的原码
11111111111111111111111111111110//-1的反码
11111111111111111111111111111111//-1的补码
00000000000000000000000000000001//相加
100000000000000000000000000000000//进1,截断多余的部分,即为0

원래 코드를 사용하여 원래 코드를 추가하는 경우

00000000000000000000000000000001//1的原码
10000000000000000000000000000001//-1的原码
10000000000000000000000000000010//结果为-2

위의 예에서 메모리에서 계산을 위해 2의 보수 코드가
사용됨을 명확하게 알 수 있습니다.VS에서 실행하면

여기에 이미지 설명 삽입

양수의 원래 부정은 동일하며 0x는 16진수 표현을 나타냅니다.

-1은 모두 1을 저장하고 16진수 표현은 ff ff ff ff를 표시합니다.

-1은 모두 1을 저장하고 16진수 표현은 ff ff ff ff를 나타냅니다.

그런데 수상한 현상을 발견했는데
왜 수납이 거꾸로 되어 있는 걸까요? 이것은 빅 엔디안 과 스몰 엔디안 이 무엇인지
말해야 합니다.

:
빅 엔디안(스토리지) 모드는 메모리의 상위 주소에 하위 비트의 데이터를 저장하고 메모리의 하위 주소에 상위 비트의 데이터를 저장하는 것을 의미하며, 리틀 엔디안(스토리지) 모드

하위 데이터의 비트는 메모리의 하위 주소에 저장되고 데이터의 상위 비트는
메모리의 상위 주소에 저장됩니다 .

여기에 이미지 설명 삽입
위와 같은 다이어그램

다음 단계는
Baidu 인터뷰 질문인 제 시간에 통합하는 것입니다.

빅 엔디안과 리틀 엔디안의 개념을 간략하게 설명하고 현재 기계의 바이트 순서를 결정하는 작은 프로그램을 설계하십시오.

컨셉은 끝났으니
바로 실전으로 갑시다

int check_sys()
{
    
    
     int i = 1;
     char* p=(char*)&i;
     return *p;
}
int main()
{
    
    
      int ret = check_sys();
      if(ret == 1)
     {
    
    
       printf("小端\n");
     }
      else
     {
    
    
      printf("大端\n");
     }
 return 0;
 }

주제 교육

( 트레이닝 효과를 강화하기 위해 조금 더 많은 질문이 있습니다 )
질문 1

1. 출력은 무엇입니까?
#include <stdio.h>
int main()
{ char a= -1; 부호 있는 char b=-1; 부호 없는 char c=-1; printf("a=%d,b=%d,c=%d" ,a,b,c); 0 반환; }





-1是整数
11111111111111111111111111111111//补码
//因char只能存放8字节,故阶段多余的
11111111//a中实际存放的
//注意:%d是10进制形式,打印有符号
//     %u是10进制形式,打印无符号
//则a先整形提升
11111111111111111111111111111111
10000000000000000000000000000001//转换成原码为-1,打印的即为-1
//signed char同理
//对于unsigned char -1在c中实际存放的也是
11111111
00000000000000000000000011111111//整形提升(无符号提升0)
//故打印的为255

질문 2

#include <stdio.h>
int main()
{ char a = -128; printf("%u\n",a); 0을 반환합니다. }



10000000000000000000000010000000//原码
11111111111111111111111101111111//反码
11111111111111111111111110000000//补码
10000000//a中实际存储
11111111111111111111111110000000//整形提升
//因为以%u的形式打印,每位都是有效位
结果为4294967168

질문 3

int i= -20;
unsigned int j = 10;
printf("%d\n", i+j);
//2의 보수 형태로 작동하고 마지막으로 부호 있는 정수로 형식화

11111111111111111111111111101100//i补码
00000000000000000000000000001010//j补码
11111111111111111111111111110110//结果的补码
10000000000000000000000000001010//结果的圆码
故结果为-10

질문 4

부호 없는 정수 i;
for(i = 9; i >= 0; i–)
{ printf("%u\n",i); }

맞아요 주제가 간결할수록 구덩이는 커져요
unsigned는 양수든 음수든 양수라는 것을 알아야 답이 무한루프임은
자명합니다 .

질문 5

int main()
{ char a[1000]; 정수 i; for(i=0; i<1000; i++) { a[i] = -1-i; } printf("%d",strlen(a)); 0을 반환합니다. }








여기에 이미지 설명 삽입
이 파이를 읽은 후에 당신이 똑똑하다고 믿으십시오. 깨달음이 있어야 합니다.

부동 소수점

드디어 여러분을 기다립니다 ~~
먼저 소개

int main()
{
    
    
 int n = 9;
 float *pFloat = (float *)&n;
 printf("n的值为:%d\n",n);
 printf("*pFloat的值为:%f\n",*pFloat);
 *pFloat = 9.0;
 printf("num的值为:%d\n",n);
 printf("*pFloat的值为:%f\n",*pFloat);
 return 0;
}

잘 생각해보고
정답을 공개해주세요
1번과 4번은 모두 문제가 없다고 생각합니다
여기에 이미지 설명 삽입
왜 이런 일이 발생할까요 저장 방법이
다르기 때문에 단순한 원본과 역보완 부호가 아닙니다 왜 안 되는지에 대해서는 , 봐주세요~~

국제 표준 IEEE(Institute of Electrical and Electronics Engineering) 754에 따르면 모든 이진 부동 소수점 숫자 V는 다음과 같은 형식으로 표현할 수 있습니다 .

1· (-1)^S * M * 2^E
2· (-1)^S는 부호 비트를 나타내며 S=0일 때 V는 양수이고 S=1일 때 V는 음수입니다.
M은 1보다 크거나 같고 2보다 작은 유효한 숫자를 나타냅니다.
3· 2^E는 지수를 나타냅니다.

읽으신 후 헷갈리실 거라 생각합니다 십진법에 대해
간단히 설명드리자면 : 5.5는 이진법으로 변환됩니다 이진법 : 101.1IEEE 표준에 따라 작성된 1.011*2^2 는 (-1)^0 × 1.011 ×2^2 to get S=0; M=1.011; //항상 1의 형태로 변환 가능 E=2 다음과 같이 저장 32비트 부동 소수점 숫자의 경우, 최상위 1비트는 부호 Bit s이고 다음 8비트는 지수 E이며 나머지 23비트는 유효숫자 M입니다. 64비트 부동 소수점 숫자의 경우 최상위 비트는 부호 비트 S이고 다음 11비트는 지수 E이며 나머지 52비트는 유효 숫자 M입니다.



여기에 이미지 설명 삽입








여기에 이미지 설명 삽입

여기에 이미지 설명 삽입

수납은 간단하게 넣기만 하면 되는 노노논 ~ M

앞서 언급한 바와 같이 1≤M<2, 즉 M은 1.xxxxxx의 형태로 쓸 수 있으며 여기서 xxxxxx는 소수점 이하를 나타낸다.
IEEE 754에서는 M이 컴퓨터 내부에 저장될 때 이 숫자의 첫 번째 자리는 기본적으로 항상 1이므로 무시할 수 있으며 다음 xxxxxx
부분만 저장하도록 규정하고 있습니다. 예를 들어 1.01을 저장할 때
01만 저장하고 읽을 때 처음 1을 추가합니다. 이렇게 하는 목적은 1개의 유효 숫자를 저장하는 것입니다. 32비트
부동 소수점 숫자를 예로 들면 M에는 23비트만 남습니다.
처음 1을 버린 후 24개의 유효 숫자를 저장할 수 있습니다.

E 에 관해서 는 조금 복잡하고 추상적입니다 (문제를 이해하는 것은 중요하지 않습니다. 결국 고대 보스 테이블에서 논의되었습니다)

먼저 E는 무부호 정수(unsigned int)로
, E가 8비트일 때 값의 범위는 0~ 255이고, E가 11비트일 때 값의 범위는 0~ 2047이다. 그러나 과학적 표기법에서 E 는 음수를 가질 수 있으므로 IEEE 754에서는 메모리에 저장할 때 E의 실제 값에 중간 숫자를 추가해야 한다고 규정하고 있습니다.8비트 E의 경우 이 중간 숫자는 127
입니다 . -비트 E, 이 중간 숫자는 1023입니다. 예를 들어 2^10의 E는 10이므로 32비트 부동소수점수로 저장할 때 10+127=137, 즉 10001001로 저장해야 합니다 .



E 넣고 이해하면 다음 단계는 꺼내는 방법입니다.

E는 모두 0이 아니거나 모두 1이 아닙니다 (일반적으로).

이때 부동 소수점 수는 다음과 같은 규칙으로 표현됩니다. 즉, 계산된 지수 E의 값에서 127(또는 1023)을 빼서 실수 값을 구한 다음 첫 번째 숫자 1을 앞에 더합니다
. 유효숫자 M
예를 들어
0.5(1/2)의 이진수 형식은 0.1이고 양의 부분은 1, 즉 소수점을 오른쪽으로 1비트 이동해야 하므로
1.0*2^(-1) 이 됩니다. , 그 순서 코드는 -1+127= 126이고,
01111110으로 표현되며, 가수 1.0은 정수 부분을 0으로 제거하고 0에서 23자리 000000000000000000000000을 채웁니다. 그러면 이진
표현은 다음과 같습니다.

0 01111110 00000000000000000000000

E는 모두 0입니다.

이때 1-127(또는 1-1023)에 해당하는 부동소수점수의 지수 E는 실수값이며,
유효숫자 M은 더 이상 1의 첫 자리에 더하지 않고 a로 복원된다. 0.xxxxxx의 십진수.
이것은 ±0과 0에 가까운 매우 작은 숫자를 나타내기 위해 수행됩니다 .

E는 모두 1입니다.

이때 유효숫자 M이 모두 0이면 ±무한대(부호비트 s에 따라 양수 또는 음수)를 의미한다.

이제 시작 인용문을 설명할 수 있습니다.
여기에 이미지 설명 삽입

n中存储9
0 00000000 00000000000000000001001//正数原码即补码
&n之后强转为float*类型
以浮点型的形式打印,对照下表
则S放0,E为00000000,M为00000000000000000001001
按照(-1)^S * M * 2^E形式写出
(-1^0× 0.00000000000000000001001×2^-126
显然,V是一个很小的接近于0的正数,所以用十进制小数表示就是0.000000

여기에 이미지 설명 삽입

*pFolat赋值为9.0,也就是以浮点数的形式存储
9.0的二进制
1001.0
即(-1^0×00100000×2^3
 s=0, M=1.001,E=3+127=130
 放入内存中
 0 10000010 00100000000000000000000%d的形式打印
 正是 1091567616

추가를 환영합니다

추천

출처blog.csdn.net/2301_78636079/article/details/132113486