음수 float에서 unsigned int으로 캐스팅할때 값이 ARM과 Intel이 다른 이유

프로그래밍을 하다 보면, 하나의 값이 이동하면서 여러번 형변환 되는 경우가 많다.


unsigned int에서 int로, 또는 float 에서 int로.. 등등 여러 가지의 형변환을 발생 시킬 수 있는데, 소숫점 자리까지 똑같은 값을 원하지 않는 다면, 큰 문제는 발생하지 않을 것이다.


그런데, 다음과 같은 경우에 문제가 발생하였다.

- 음수를 가진 float에서 unsigned int로 캐스팅하는 경우.

- 음수를 가진 unsigned int에서 float으로 캐스팅하는 경우. (unsigned int는 음수 int를 캐스팅해놓은 상태)


위와 같은 상황이 이해가 되지 않는다면, 아래 예제를 보면 바로 상황 파악이 될 것이다.


사실, 위와 같은 상황을 그리 많이 겪지는 않으리라 생각한다. 보통 임베디드 개발을 하는 사람들이 겪을 만한 일이라..

그 이유는 인텔 환경에서는 문제 없이 정상적으로 캐스팅 되는 반면에, ARM 계열에서는 위와 같이 0으로 변환되기 때문이다.


# ARM과 INTEL 계열, 위와 같은 캐스팅 차이가 나는 이유는?

위 코드는 -3, 또는 4294967293 값을 변수에 대입하는 것이 목적이다. 즉, 2의 보수 표현으로 변수에 값이 들어가 있기를 원한 다는 것이다.


하지만 ARM 계열에서는 0 또는 이상한 값으로 변환 되는 이유는 모든 음수인 실수가 0으로 판단하기 때문이라고 한다. 음수인 float 타입의 2의 보수로 연산되지 않는다는 것 때문이라한다.

즉, 음수의 float를 unsigned int로 형변환할 때 안전한 범위는 -1부터 정수 최대 값까지라고 합니다.


# 그럼 이것을 해결할 수 있는 방법은?

한 홈페이지를 참고해보니, 해결 방법은 아래와 같다.


즉, float형의 실수를 unsigned int로 바꾸고자 한다면, int형의 정수로 변경 과정이 있어야 한다는 것이다. 명시적으로 형변환을 하라는 것이다.


이와 같이 입력하면 원하는 값이 나오는 것을 확인할 수 있을 것이다.

참고 : https://www.embeddeduse.com/2013/08/25/casting-a-negative-float-to-an-unsigned-int/

댓글