int와 float 연산

반응형

int a = 6600;

int result = (int)((float)a * 0.01f);

이렇게 하면 result 값은 66이 되어야 하지만 65가 된다.


정상적으로 하기 위해서는 이렇게 해야 한다.

nt a = 6600;

(int)Mathf.Round(a * 0.01f );


혹시나 해서 추가 개별 연산 테스트를 해 봤다.

int a = 6600;

int result = (int)((float)a * 0.01f); // result 결과 65


float bb = (float)a * 0.01f; // bb 결과 66

int cc = (int)66f; // cc 결과 66

int dd = (int)bb; // cc 결과 66


그래서 시작한 디스어셈블리

C++

int a = 6600;

00CA436E  mov         dword ptr [a],19C8h    // a에 값복사

int result = (int)((float)a * 0.01f);  // result는 65

00CA4375  cvtsi2ss    xmm0,dword ptr [a]  // 4바이트 정수를 단정도 실수형의 스칼라 값으로 변환

00CA437A  mulss       xmm0,dword ptr ds:[0CACD80h]   // 단일 정밀도 부동 소수점 값과 스칼라 값을 곱한다

00CA4382  cvttss2si   eax,xmm0             

00CA4386  mov         dword ptr [result],eax  


float bb = (float)a * 0.01f; // bb 결과 66

00CA4389  cvtsi2ss    xmm0,dword ptr [a]  

00CA438E  mulss       xmm0,dword ptr ds:[0CACD80h]  

00CA4396  movss       dword ptr [bb],xmm0   // 단일 정밀도 부동 소수점 값을 두번째 피연자에서 첫번째 피연산자로 이동.

int dd = (int)bb; // cc 결과 66

00CA43A2  cvttss2si   eax,dword ptr [bb]  

00CA43A7  mov         dword ptr [dd],eax  


위 두 과정을 비교해 보면 두번째 과정에서 cvttss2si 전에 movss가 있다.

cvttss2si는 간단하게 실수형 체계를 정수형 체계로 전환하는 명령어 셋이라고 볼 수 있다.

그렇다면 위의 결과값이 65가 나오는 코드와 아래 66이 나오는 코드의 차이점은 실수를 정수로 바꾸기 바로 전에

movss로 float값을 한번 저장하는 것에 있다고 이해하면 될까?

위 cvttss2si와 아래의 cvttss2si를 보면 dword가 있는데 dword ptr은 4바이트 단위로 접근하겠다는 의미이다.




C#

int a = 6600;

00000044  mov         dword ptr [ebp-40h],19C8h 

int result = (int)((float)a * 0.01f);

0000004b  fild        dword ptr [ebp-40h] 

0000004e  fstp        dword ptr [ebp-54h] 

00000051  fld         dword ptr [ebp-54h] 

00000054  fmul        dword ptr ds:[001F26F8h] 

0000005a  fstp        qword ptr [ebp-5Ch] 

0000005d  movsd       xmm0,mmword ptr [ebp-5Ch] 

00000062  cvttsd2si   eax,xmm0 

00000066  mov         dword ptr [ebp-44h],eax 

float bb = (float)a * 0.01f; // bb 결과 66

00000069  fild        dword ptr [ebp-40h] 

0000006c  fstp        dword ptr [ebp-54h] 

0000006f  fld         dword ptr [ebp-54h] 

00000072  fmul        dword ptr ds:[001F2700h] 

00000078  fstp        dword ptr [ebp-48h] 

int cc = (int)66.0f; // cc 결과 66

0000007b  mov         dword ptr [ebp-4Ch],42h 

int dd = (int)bb; // cc 결과 66

00000082  fld         dword ptr [ebp-48h] 

00000085  fstp        qword ptr [ebp-5Ch] 

00000088  movsd       xmm0,mmword ptr [ebp-5Ch] 

0000008d  cvttsd2si   eax,xmm0 

00000091  mov         dword ptr [ebp-50h],eax 


어렵다 어려워. 


Reference Link

- http://www.gamecodi.com/board/zboard.php?id=GAMECODI_Talkdev&no=2947&z=4

-

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

random  (0) 2014.11.29
factory function (팩토리 함수)  (0) 2012.05.12
Hash 함수 모음  (0) 2011.04.22
boost::has_trivial_assign  (0) 2011.04.10
메모리맵 파일  (0) 2011.04.09
TAGS.

Comments