211
2011-06-06 09:08:34
0
자료구조나 컴퓨터공학개론같은데서 정수형 데이터의 자료 저장방법을 배우셨다면 이해가 빠르실텐데, 그렇진 않으시니 일단 기초부터 쉽게 풀어보겠습니다.
일단 컴퓨터는 모든 데이터를 0과 1로 이루어진 2진수로 저장합니다.
예를들어 10진수의 2 는 2진수의 10 이고 10진수의 13은 2진수의 1101 입니다.
그리고 실제로 프로그래밍에서 각 정수형 자료형에 수를 저장할 때도 이와같이 저장을 합니다.
자바에서 int의 경우에는 32비트(4바이트)의 길이를 지니고 있으니 최대 11111111111111111111111111111111의 수까지 표현 할 수 있습니다.(10진수로는 2^32 - 1 입니다.)
그런데 이렇게 저장을 할 경우 음수를 표현 할 수 없게 됩니다.
그래서 해법으로 생각한 것이 제일 앞의 비트가 0이면 양수, 1이면 음수라고 하고, 실제로 수가 저장되는건 나머지 31비트만 숫자를 나타내게 했습니다.
따라서 10진수 -10 의 경우엔 메모리에 10000000000000000000000000001010 라고 저장이 되죠.
결국 int에 저장 가능한 수는 10진수로 2^31-1 ~ -(2^31-1) 이 됩니다.
그리고 제일 앞 비트를 부호 표시를 않고 그냥 수를 표시하는데 쓰라고 지정할 수 도 있는데 그게 unsigned 입니다.
영어를 그대로 해석하면, 표시하는데 쓰지 않는 이네요.
아무튼 이렇게 각 변수는 정해진 비트수만큼 크기를 제한받게 됩니다.
그런데 이 크기보다 큰 값이 오게되면 원래보다 큰 값이 들어온 에러, 오버플로우가 일어나는거죠.
음수의 경우에는 범위보다 작은 값이 오면 오버플로우 에러가 나겠죠.
아무튼, 이때 오버플로우된 자료는 버려지는게 아니라, 최대한 담을 수 있는데까지 변수에 담으려고 합니다.
따라서 최상위에 잘려나간 몇 비트를 제외하고 나머지 비트는 변수에 넣어두는거죠.
문제는, 이렇게 우겨 넣으면서 최 상위의 부호표십비트까지 덮어써 버리기 때문에 연산 겨로가에 따라 부호가 바뀌게 됩니다.
즉, 항상 양수로 바뀌는 것이 아니라 계산 결과에 따라 전혀 다른 값이 올 수 있습니다.
보통은 프로그래밍을 할 때 이런 일이 일어나지 않도록 프로그래밍을 해야겠죠.(일부러 에러를 유도하지 않는한요)
아무튼, 음수의 뺄셈뿐 아니라 오버플로 직전의 수 두개를 곱하면 훨씬 더 다양한 결과의 에러를 볼 수 있습니다.