What’s 가장 작은 0 보다 큰? 이것은”아무도 없다”와”의존한다”사이의 복잡한 대답이있는 간단한 질문 중 하나입니다.
당신이 수학자에게 물어 보면,그들은 수학을 깰 것이기 때문에 그런 숫자가 될 수 없다고 말할 것입니다. 만약 당신이 숫자 엔,여기서 엔 0 이후 가장 작은 숫자라면 숫자가있을 수 없습니다 엔/2,왜냐하면 엔 이미 가장 작기 때문입니다. 이것은 수학자들이 좋아하지 않는 분할 자체가 분해된다는 것을 의미합니다.
당신이 컴퓨터를 요구하는 경우에,당신은 실제로 대답을 얻을 것이다. 현실 세계와 달리 컴퓨터는 단순히 들어갈 수 없기 때문에 무한한 숫자를 가지고 있지 않습니다. 컴퓨터는 메모리 레지스터에 번호를 저장하며 각 레지스터에는 고정 된 비트 수가 있습니다. 세 자리 숫자 만 있다고 상상해보십시오. 당신이 대표 할 수있는 가장 큰 숫자는 999 입니다. 이것은 컴퓨터에서 일어나는 일입니다.
이것은 컴퓨터의 정수 집합이 자릿수에 의해 제한된다는 것을 의미합니다. 컴퓨터에는 확실히 가장 큰 숫자가 있습니다(예:INT_MAX
). 이 숫자는 최대 자릿수이며 모두 이진1
으로 설정됩니다. 8 비트 시스템에서 이 숫자는11111111
입니다.
우리는 음수를 포함함으로써 문제를 더욱 복잡하게 만들 수 있습니다. 8 비트의 데이터가 있다면 첫 번째 비트를 사용하여 숫자의 부호를 나타낼 수 있습니다. 플러스의 경우0
,마이너스의 경우1
. 이제 우리는 우리의 숫자에 대해 7 비트를 가지고 있으므로 가장 큰 숫자는 이전의 가장 큰 숫자보다 작은011111111
입니다.
우리는 아직 끝나지 않았습니다. 우리는 또한 십진수를 나타낼 필요가 있습니다. 0.12 가 작은 숫자 일지라도 여전히 123 과 같이 세 자릿수가 있습니다. 차이점은 우리가 생각해야 할 것이 하나 더 있다는 것입니다:소수점,기수 점이라고도 합니다. 우리는 숫자 및 기수 점의 위치를 모두 저장해야합니다.
정수가 얼마나 큰지 제한되지만 10 진수는 크기와 정밀도 모두에서 제한됩니다. 당신은 숫자의 고정 된 번호가있는 경우,당신은 소수점 뒤에 넣을 수 있습니다 만 많은 자리가있다. 이 때문에 컴퓨터는 10 진수를 반올림 해야 합니다.
이 10 진수를 어떻게 저장합니까? 컴퓨터는 정수 만 이해하므로 정수를 사용하여 10 진수 만 저장하는 방법이 필요합니다.
숫자3.14
가 있다고 가정 해 봅시다. 먼저 모든 숫자를 써봅시다 우리는314
을 얻습니다. 그게 시작이야. 우리는 10 의 제곱을 곱하면 소수점을 숫자 주위로”이동”할 수 있다는 것을 알고 있습니다. 314 * 10^-1
은 31.4 이고314 * 10^-2
는 3.14 입니다.
숫자 3.14 를 나타내는 데 필요한 것은 314,10 및-2 의 세 가지 정수입니다. 314 는 유효숫자이고,이 숫자는 모두 적힌 숫자입니다.
10 은 기수 또는 기수라고합니다. 우리는 10 의 제곱을 곱하면 10 진수의 소수점을 이동할 수 있다는 것을 알고 있습니다. 모든 숫자 기지에 대해 동일한 작동: 기본 2(또는 이진)에서 2 의 제곱을 곱하여 점을 이동할 수 있습니다.
우리가 이동하는 제곱을 지수라고 하며,소수점이 어디에 있는지 알려줍니다.
모든 10 진수를 간단한 수식으로 세 숫자로 쓸 수 있습니다:
number = significand * base^exponent3.14 = 314 * 10^-2
32.8 = 328 * 10^-1
컴퓨터는 부호,지수 및 유효 숫자를 32 또는 64 비트 자리의 단일 문자열에 저장하여 10 진수를 저장합니다. 일반적으로 부호에는 1 비트,지수를 저장하는 11 비트,유효 숫자를 저장하는 53 비트가 있으며 최대 64 를 더합니다.
그 점을 염두에두고,우리의 질문으로 돌아 가자: 가장 작은 0 이 아닌 숫자는 무엇입니까? 세 자리 숫자만 빼면 가능한 가장 작은 숫자는 0.01 입니다. 네 자리 숫자로 0.001 입니다. 여기서 패턴을 알 수 있습니다:유효 숫자는 항상 동일하며 지수 만 변경됩니다.
우리에게 필요한 것은1
의 유효 숫자입니다. 소수점을 왼쪽으로 옮겨야 합니다 이를 위해서는 가능한 가장 작은(가장 부정적인)지수가 필요합니다.
얼마나 작은,메모리의 숫자의 레이아웃에 따라 달라집니다. 만약 우리가 지수에 대해 11 비트를 가지고 있다면,우리는 단지 10 비트 길이의 숫자를 쓸 수 있으며,부호를 위해 1 비트를 예약 할 수 있습니다. 64 비트 시스템에서 가장 작은 지수는-308
입니다.
결국 64 비트 시스템에서 가능한 가장 작은 숫자는1 * 10^-308
정도입니다. 즉 작은입니다!
우리는 가장 작은 숫자가 있음을 확립했습니다. 이 숫자는 우리가 컴퓨터를 얼마나 신뢰할 수 있는지 알려줍니다. 매우 큰 숫자 또는 매우 정확한 숫자가 필요한 작업을 수행하는 경우 이 숫자를 염두에 두어야 합니다.
우리가 방금 계산한 것은 0 의 마지막 자리에 있는 단위입니다. 정말 멋진 단어 인 것 외에도,울프는 컴퓨터에서 두 숫자 사이의 최소 거리가 무엇인지 알려줍니다. 우리는 0 과 다음 숫자 사이의 최소 거리 인 0 의 울프를 계산했습니다.
계산된 값을 0 에 더하고 비교하려고 하면 같은 숫자가 아닙니다. 그러나 이 값보다 작은 값을 더하면 컴퓨터에 관한 한 여전히 같은 숫자가 됩니다.
print(0 == 0 + ulp(0)) // false
print(0 == 0 + ulp(0) / 2) // true
우리에게는 0 이 아닌 값을 숫자에 더하면 다른 숫자가 생성되지만 컴퓨터는 어딘가에 반올림해야하므로 두 숫자가 같은지 반드시 알 수는 없습니다.
컴퓨터 시스템을 더 쉽게 비교하기 위해 우리는 1 의 울프를 사용하고 그것을 기계 엡실론이라고 부릅니다. 기계 엡실론을 알고 나면 다음 공식을 사용하여 다른 모든 울프를 계산할 수 있습니다:
ulp(x) = machine epsilon * radix^exponent(x)
우리가 계산 한 값은 매우 작기 때문에 코딩하는 동안 그 한계에 미치지 못할 것입니다. 그러나 우리는 0 에 대한 값을 계산했습니다. 소수점의 왼쪽에 필요한 숫자가 많을수록 오른쪽에 필요한 숫자가 적어집니다. 즉,숫자가 클수록 정밀도가 떨어집니다. 즉,지수의 직접 함수입니다. 10 진수 점을 오른쪽으로 이동하면 울프가 증가하고 정밀도가 떨어집니다.
이 정보가 다음에 코드에서 이상한 부동 소수점 오류가 발생할 때 도움이되기를 바랍니다. 컴퓨터는 매우 강력하지만 컴퓨터조차도 한계가 있다는 것을 기억하십시오.