source

메모리에서 FLOOT 번호를 C로 표현하는 방법

manysource 2023. 11. 6. 21:54

메모리에서 FLOOT 번호를 C로 표현하는 방법

튜토리얼을 읽다가 Float number를 메모리에 표현하는 방법을 발견했습니다.자습서에는 부동 소수점 번호가 포함된 예제가 있습니다.

   float a=5.2  with below Diagram

enter image description here

위 도표에서 이 5.2가 어떻게 이진법으로 변환되고 메모리에 어떻게 표현되는지 누가 말해줄 수 있습니까?

앞서 말한 것처럼 5.2는 부호 비트, 지수 및 가수로 표현됩니다.5.2를 어떻게 인코딩합니까?

5는 쉽습니다.

101. 

나머지 0.2는 1/5이니 나누세요.1.00000...(hex) 5시까지 당신은0.3333333...(16진수).

(이는 한 가지만 덜 고려한다면 더 쉽게 따라 할 수 있습니다.0.FFFF...F / 5 = 3, 그래서 쉽게 알 수 있습니다.0.FFFF... / 5 = 0.33333.... 5로 나눌 때 빠진 비트 하나는 중요하지 않아요.1.0000... / 5 = 0.3333...역시).

그러면 당신에게 줄 겁니다.

0.0011001100110011001100110011... 

5를 더하면 당신은

101.00110011001100110011...         exp 0    (== 5.2 * 2^0)

이제 오른쪽으로 이동하고(정규화합니다. 예를 들어 상위 비트가 소수점 바로 앞에 있는지 확인합니다.) 지수를 그에 따라 조정합니다.

1.010011001100110011001100110011... exp +2   (== 1.3 * 2^2 == 5.2)

이제 127의 편의만 더하면 됩니다.129 = 0b10000001) 지수에 저장합니다.

0 10000001 1010 0110 0110 0110 0110 0110 

가수(일부 특수 값을 제외하고는 항상 1이어야 하므로 저장되지 않음)의 맨 위 1을 잊어 버리면 다음을 얻을 수 있습니다.

01000000 10100110 01100110 01100110

이제 여러분은 작은 엔디안이나 큰 엔디안만 결정하면 됩니다.

이것은 정확히 이것이 작동하는 방식은 아니지만, 그것은 5.2와 같은 숫자가 이진법으로 변환될 때 발생하는 것입니다.

나는 그 도표가 100퍼센트 정확하지 않다고 생각합니다.

플로트는 다음과 같이 메모리에 저장됩니다.

이들은 다음과 같이 분류됩니다.

  • 서명하다s(긍정인지 부정인지 표시) - 1bit
  • 가수m(본질적으로 당신 숫자의 숫자 - 24비트)
  • 기특한e- 7비트

그러면 아무 숫자나 쓸 수 있습니다.x~하듯이s * m * 2^e어디에^는 지수화를 나타냅니다.

5.2는 다음과 같이 표시해야 합니다.

0 10000001 01001100110011001100110    
S    E               M

S=0는 양수임을 나타냅니다. 즉,s=+1

E다음을 나타내는 부호 없는 숫자로 해석됩니다.129. 127을 빼야 합니다.E원 지수를 구하다e = E - 127 = 2

M다음과 같이 해석해야 합니다.그것은 a로 시작하는 숫자로 해석됩니다.1다음에 한 점(.그 다음에 숫자가 표시됩니다.뒤의 숫자는.실제로 암호화되어 있는 것들입니다.m. 각 숫자에 대한 가중치를 소개합니다.

bits in M: 0   1    0     0      1       ... 
weight:    0.5 0.25 0.125 0.0625 0.03125 ... (take the half of the previous in each step)

이제 해당 비트가 설정된 가중치를 합산합니다.이 일을 한 후에, 당신은 추가합니다.1(IEEE 표준의 정규화로 인해 해석을 위해 항상 1을 추가합니다.M) 및 원본을 가져옵니다.m.

이제, 당신은 컴퓨터로x = s * m * 2^e원래 번호를 받아보세요.

따라서, 남은 것은 실제 메모리에서 바이트가 역순일 수 있다는 것입니다.따라서 다음과 같이 번호를 저장할 수 없습니다.

0 10000001 01001100110011001100110    
S    E               M

하지만 그 반대의 경우가 더 많습니다(simply은 8비트 블록을 사용하여 순서를 미러링합니다).

01100110 01100110 10100110 01000000
MMMMMMMM MMMMMMMM EMMMMMMM SEEEEEEE

값은 메모리에 역순으로 표시되지만 부동 소수점 값의 정확도 손실로 인해 5.2f가 실제로 5.1999998로 표시되는 것이 혼란스러울 수 있습니다.

5.2를 표현하는 것은 이진 논리에서 매우 간단합니다.

     8 4 2 1
5 -> 0 1 0 1

10진수의 경우:

.2를 취하고 2를 곱합니다(이진법으로 나타내므로).

.2 X 2 = 0.4 -> take the value after the
                decimal point, don't take the value before
                the decimal point

.4 X 2 = 0.8
.8 X 2 = 1.6
.6 X 2 = 1.2
.2 X 2 = 0.4

등등...

이 단계가 끝나면 위 단계의 출력에서 소수점 앞의 값을 취합니다.

.2 X 2 = 0.4 -> take 0 from this for representing in binary form

따라서 5.2의 최종 o/p는 다음과 같습니다.

0101.00110...

원시 플로트 5.2:

01000000101001100110011001100110
^ sign bit

메모리에서 역 바이트 순서(그림과 같이):

01100110011001101010011001000000
                        ^ sign bit

5.2

번호는 "Sign Bit, Exponent, Mantissa" 형태로 저장됩니다.5의 이진법으로8 4 2 1그렇게0101그리고 .2는

.2*2=.4   0
.4*2=.8   0
.8*2=1.6  1

숫자가 양수이기 때문에 비트 0에 부호를 붙입니다.

0 0101 001....

5.2 in 바이너리 101.00110011......--------> 정규화되지 않은 형태 5.2는 .10100110011......x 2^3 ------> 명시적 정규 형태 5.2는 암시적 정규 형태에서 .0100110011 x 2^3입니다.

여기서 부호 비트는 0이 되고(숫자가 양수이기 때문에) 지수는 7비트이므로 초과 64 지수 표기를 사용하므로 지수는 64+3 = 69,000101이 되고 나머지는 가수가 됩니다(총 32비트 - 7 지수 비트 - 1 부호 비트 = 24비트) 01001100110011001100

위의 예제에서 부호 비트는 정확합니다 64 초과가 적용되지 않으므로 정규화되지는 않지만 이상적으로 MSB '1'이 오지 않을 경우 second byte에서 암묵적 정규화 Tantissa part를 사용해야 합니다.

5.2는 "0100000010100110011001100110"으로 표시됩니다.

Converter 애플릿 확인

원래 다른 웹사이트에 게시된 변환 기법은 불필요하게 복잡한 것으로 보여집니다. (우리가 정답을 맞추는데도) 메모리에서 5.2의 메모리를 표현하는 경우:

먼저 간단한 이진 시스템으로 변환하면 101.0011001100110011001100110011을 얻을 수 있습니다.

이제 과학적 형태로 바꿉니다: 1.0100110011001100110011001100110011 x 10^2.

이제 숫자가 양수이므로 우리의 부호 비트는 0입니다.

지수의 경우 최대 8비트(127 + 2)가 필요하므로 10000001을 얻을 수 있습니다.

분수는 010011001100110011001100110 . (23비트) (과학 형태의 선두 1을 폐기)

=> 표현은

0 10000001 0100 1100 1100 1100 1100 110

아래의 두 가지 참고문헌은 IEE 754 부동 소수점 번호 인코딩을 이진 형식으로 이해하는 데 실질적으로 도움이 되었습니다.

http://www.pitt.edu/ ~juy9/142/슬라이드/L3-FP_Representation.pdf

http://en.wikipedia.org/wiki/Single-precision_floating-point_format

int a;
float b=5.2;
memcpy(&a, &b, 4);
printf("%d",a);

이것은 0100000010010011010011010000001 (1084647041)을 줍니다.

언급URL : https://stackoverflow.com/questions/6910115/how-to-represent-float-number-in-memory-in-c