부동 소수점 표현에 관해 SO에 게시 된 몇 가지 질문이 있습니다. 예를 들어, 십진수 0.1은 정확한 이진 표현을 가지지 않으므로 == 연산자를 사용하여 다른 부동 소수점 숫자와 비교하는 것은 위험합니다. 부동 소수점 표현의 원리를 이해합니다.
내가 이해하지 못하는 것은 수학적 관점에서 소수점 오른쪽의 숫자가 왼쪽의 숫자보다 “특별한”이유는 무엇입니까?
예를 들어, 숫자 61.0은 숫자의 정수 부분이 항상 정확하기 때문에 정확한 이진 표현을 갖습니다. 그러나 숫자 6.10은 정확하지 않습니다. 내가 한 것은 소수를 한 자리로 옮기는 것인데 갑자기 Exactopia에서 Inexactville로 갔다. 수학적으로 두 숫자 사이에는 본질적인 차이가 없어야합니다. 단지 숫자 일뿐입니다.
반대로, 숫자 610을 생성하기 위해 소수점을 한 방향으로 다른 방향으로 이동하면 여전히 Exactopia에 있습니다. 나는 그 방향 (6100, 610000000, 610000000000000)으로 계속 갈 수 있으며 여전히 정확하고 정확합니다. 그러나 소수가 임계 값을 초과하면 숫자가 더 이상 정확하지 않습니다.
무슨 일이야?
편집 : 명확히하기 위해 IEEE와 같은 산업 표준 표현에 대한 토론에서 벗어나 수학적으로 “순수한”방법이라고 생각합니다. 밑 10에서 위치 값은 다음과 같습니다.
... 1000 100 10 1 1/10 1/100 ...
바이너리에서는 다음과 같습니다.
... 8 4 2 1 1/2 1/4 1/8 ...
이 숫자에는 임의의 제한이 없습니다. 위치는 왼쪽과 오른쪽으로 무한정 증가합니다.
답변
부동 이진수 점 숫자가 아닌 충분한 공간이 있으면 십진수를 정확하게 나타낼 수 있습니다 . 부동 소수점 유형 (예 : .NET)을 사용하는 경우 이진 부동 소수점으로 정확하게 표현할 수없는 많은 값을 정확하게 표현할 수 있습니다.System.Decimal
다른 방법으로 살펴 보겠습니다. 10 단계에서는 편안하게 사용할 수 있으며 1/3을 정확하게 표현할 수 없습니다. 0.3333333 … (반복)입니다. 0.1을 이진 부동 소수점 숫자로 나타낼 수없는 이유는 정확히 같은 이유입니다. 1/3, 1/9 또는 1/27을 제외하고 3, 9, 27을 정확하게 표현할 수 있습니다.
문제는 3은 10의 요소가 아닌 소수입니다. 숫자에 3 을 곱 하려는 경우에는 문제가되지 않습니다. 문제가 발생 하지 않고 항상 정수를 곱할 수 있습니다. 하지만이 때 분할 소수와 기지의 요인이 아닌 번호로, 당신은 문제로 실행할 수 있습니다 (그리고 것입니다 당신이 그 번호로 나누어 1로하려고하면 그렇게).
일반적으로 0.1은 이진 부동 소수점으로 정확하게 표현할 수없는 정확한 십진수의 가장 간단한 예로 사용되지만 0.2는 1/5-5는 10과 이진 사이에 문제를 일으키는 소수이므로 더 간단한 예입니다. .
유한 표현 문제를 다루기위한 참고 사항 :
같은 일부 부동 소수점 유형은 고정 된 크기가 System.Decimal
다른 사람들이 좋아 java.math.BigDecimal
하지만 그들은 어떤 점에서 한계를 칠 것이다, 그것의 시스템 메모리 또는 배열의 이론적 인 최대 크기 여부 – “임의의 큰”입니다. 그러나 이것은이 답변의 주요 내용과 완전히 별개입니다. 실제로 임의로 많은 수의 비트를 연주하더라도 부동 이진수 점 표현에서 정확히 10 진수 0.1을 표현할 수 없습니다. 다른 방법으로 라운드와 비교하십시오 : 임의의 소수 자릿수가 주어지면 부동 이진수로 정확하게 표현할 수있는 모든 숫자를 정확하게 나타낼 수 있습니다 .
답변
예를 들어, 숫자 61.0은 숫자의 정수 부분이 항상 정확하기 때문에 정확한 이진 표현을 갖습니다. 그러나 숫자 6.10은 정확하지 않습니다. 내가 한 것은 소수를 한 자리로 옮기는 것인데 갑자기 Exactopia에서 Inexactville로 갔다. 수학적으로 두 숫자 사이에는 본질적인 차이가 없어야합니다 . 단지 숫자 일뿐입니다 .
베이스 10과 2의 세부 사항에서 잠시 벗어나 보자.베이스를 물어보고 b
, 어떤 숫자로 끝나는 표현이 있고, 어떤 숫자가 그렇지 않은가? 잠시 생각 하면 정수 와 같은 정수가있는 경우에만 숫자 x
에 종결 표시 가 있음을 알 수 있습니다 .b
n
x b^n
예를 들어 정수를 선택한 다음을 x = 11/500
선택할 수 있기 때문에 종료 10 표현이 있습니다 . 그러나 우리가 선택한 것이 무엇이든 우리는 3을 제거 할 수 없기 때문에 그렇지 않습니다 .n = 3
x b^n = 22
x = 1/3
n
이 두 번째 예는 요인에 대해 생각하도록 촉구하며, 합리적 x = p/q
(가장 낮은 용어로 가정)에 대해 b
와 의 소인수 분해를 비교하여 질문에 대답 할 수 있음을 알 수 있습니다 q
. 경우 q
하지의 주요 인수 분해의 모든 주요 요소를 가지고 b
, 우리는 적절한 찾을 수 없을 것입니다 n
이러한 요소를 제거 할 수 있습니다.
따라서 기수 10의 경우 2 또는 5 이외의 주요 요소가 있는 p/q
곳 q
은 종료 표현이 없습니다.
이제 10 번 기지와 2 번 기지로 되돌아 가면, 10 번 표현이 끝나는 모든 합리적 요소가 1 차 분해에 s와 s 만 p/q
있을 때 의 형태가 될 것입니다 . 그리고 같은 수는 소인수 분해 만 있을 때 정확하게 2 차 종료를 나타냅니다 .q
2
5
q
2
그러나 이러한 경우 중 하나는 다른 하나의 일부입니다. 할때는 언제나
q
이 단지2
의 주요 인수 분해에이야
그것은 또한 사실이다
q
소인수 분해에서2
s와5
s 만 있음
또는 다른 방법으로, 종료 2 표현이 있을 때마다 종료 10 표현이p/q
p/q
있습니다. 반대의 그러나 않습니다 하지 개최 – 때마다 q
그 주요 인수 분해에 5를 가지고, 그것은 종료 10 표현하지만 것 없는 종단이-표현을. 이것은 0.1
다른 답변에서 언급 한 예입니다.
따라서 2의 소인수는 10의 소인수의 부분 집합이므로 모든 2 개의 종료하는 숫자는 10 개의 종료하는 숫자이지만 그 반대도 아닙니다. 약 61 대 6.1이 아니며 약 10 대 2입니다.
기부 (5) 사용되는 몇 가지 특질을 사용하는 사람 (말) 기본 17 그러나 우리의 컴퓨터에서, 당신의 직관이에 의해 타락 주도되지 못했을 경우 닫는 참고로, – 없을 것이다 아무 종료 (0이 아닌 정수가 아닌) 번호 두 경우 모두!
답변
근본 (수학적) 이유는 정수를 처리 할 때 그 수가 무한히 많기 때문 입니다.
즉, 무한한 양이 있더라도 순서의 모든 항목을 건너 뛰지 않고 “계산”할 수 있습니다. 즉 610000000000000
, 목록에서 세 번째 위치에 항목을 가져 오려면 수식을 통해 항목을 파악할 수 있습니다.
그러나 실수는 셀 수없이 무한 합니다. 당신은 “위치에 실제 숫자를 줘”라고 말하고 610000000000000
답을 얻을 수 없습니다 . 부동 소수점 값을 고려할 때 0
및 사이에도 1
무한 수의 값 이 있기 때문 입니다. 두 개의 부동 소수점 숫자에 대해서도 마찬가지입니다.
더 많은 정보:
http://en.wikipedia.org/wiki/Countable_set
http://en.wikipedia.org/wiki/Uncountable_set
업데이트 :
사과합니다. 질문을 잘못 해석 한 것 같습니다. 내 대답은 왜 우리가 모든 실제 가치를 대표 할 수 없는지에 관한 것입니다 . 나는 부동 소수점이 자동으로 합리적으로 분류된다는 것을 깨닫지 못했습니다.
답변
Mr. Skeet에 대한 의견에서 반복했던 내용 : 1/3, 1/9, 1/27 또는 10 진수 표기법으로 합리적인 표현 을 할 수 있습니다 . 추가 기호를 추가하여 수행합니다. 예를 들어, 숫자의 십진 확장에서 반복되는 숫자 위에있는 행입니다. 이진수 시퀀스로 10 진수를 나타내야하는 것은 1) 이진수 시퀀스, 2) 기수, 3) 시퀀스의 반복 부분을 나타내는 다른 기호입니다.
Hehner의 인용 표기법 은 이것을 수행하는 방법입니다. 그는 인용 부호를 사용하여 시퀀스의 반복 부분을 나타냅니다. 기사 : http://www.cs.toronto.edu/~hehner/ratno.pdf 및 위키 백과 항목 : http://en.wikipedia.org/wiki/Quote_notation .
표현 시스템에 기호를 추가 할 수 없다고하는 것은 아무것도 없으므로, 이진 따옴표 표기법을 사용하여 정확히 십진수를 표현할 수 있으며 그 반대도 마찬가지입니다.
답변
BCD- 이진 코드 10 진수 -표현이 정확합니다. 그것들은 공간 효율적이지는 않지만,이 경우 정확성을 위해해야 할 절충점입니다.
답변
기초 10에서 1/3을 정확하게 표현할 수없는 것과 같은 이유로 0.33333 (3)을 말해야합니다. 이진에서는 같은 유형의 문제이지만 다른 숫자 집합에 대해서만 발생합니다.
답변
(참고 : 여기에 이진수를 나타 내기 위해 ‘b’를 추가하겠습니다. 다른 모든 숫자는 십진수로 표시됩니다)
사물을 생각하는 한 가지 방법은 과학적 표기법과 같은 것입니다. 우리는 6.022141 * 10 ^ 23과 같은 과학적 표기법으로 표현 된 숫자를 보는 데 익숙합니다. 부동 소수점 숫자는 가수와 지수와 비슷한 형식을 사용하지만 10 대신 2의 거듭 제곱을 사용하여 내부적으로 저장됩니다.
가수와 지수를 사용하여 61.0을 1.90625 * 2 ^ 5 또는 1.11101b * 2 ^ 101b로 다시 쓸 수 있습니다. 10을 곱하고 (소수점 이동) 다음을 수행 할 수 있습니다.
(1.90625 * 2 ^ 5) * (1.25 * 2 ^ 3) = (2.3828125 * 2 ^ 8) = (1.19140625 * 2 ^ 9)
또는 가수와 지수를 바이너리로 사용하십시오.
(1.11101b * 2 ^ 101b) * (1.01b * 2 ^ 11b) = (10.0110001b * 2 ^ 1000b) = (1.00110001b * 2 ^ 1001b)
우리가 숫자를 곱하기 위해 무엇을했는지 주목하십시오. 우리는 가수를 곱하고 지수를 추가했습니다. 가수가 2보다 크게 끝나기 때문에 지수를 부딪쳐 결과를 정규화했습니다. 십진 과학 표기법으로 숫자에 대한 작업을 수행 한 후 지수를 조정하는 것과 같습니다. 각각의 경우에, 우리가 작업 한 값은 이진수로 유한 표현이되었으므로 기본 곱셈과 덧셈 연산으로 출력 된 값도 유한 표현으로 값을 생성했습니다.
이제 61을 10으로 나누는 방법을 생각해 봅시다. 가수를 1.90625와 1.25로 나눕니다. 십진수로, 이것은 짧은 숫자 인 1.525를 제공합니다. 그러나 바이너리로 변환하면 어떻게됩니까? 정수 십진수를 이진수로 변환하는 것처럼 가능한 한 항상 2의 최대 거듭 제곱을 빼는 일반적인 방법으로 수행하지만 2의 음의 거듭 제곱을 사용합니다.
1.525-1 * 2 ^ 0-> 1 0.525-1 * 2 ^ -1-> 1 0.025-0 * 2 ^ -2-> 0 0.025-0 * 2 ^ -3-> 0 0.025-0 * 2 ^ -4-> 0 0.025-0 * 2 ^ -5-> 0 0.025-1 * 2 ^ -6-> 1 0.009375-1 * 2 ^ -7-> 1 0.0015625-0 * 2 ^ -8-> 0 0.0015625-0 * 2 ^ -9-> 0 0.0015625-1 * 2 ^ -10-> 1 0.0005859375-1 * 2 ^ -11-> 1 0.00009765625 ...
어 오. 이제 우리는 곤경에 처했습니다. 1.90625 / 1.25 = 1.525는 이진수로 표현할 때 반복되는 분수입니다. 1.11101b / 1.01b = 1.10000110011 … b 우리 기계에는 가수를 담을 비트가 너무 많기 때문에 분수를 반올림합니다. 특정 지점을 넘어 0을 가정합니다. 61을 10으로 나누면 나타나는 오류는 다음과 같습니다.
1.100001100110011001100110011001100110011 … b * 2 ^ 10b
, 즉 :
1.100001100110011001100110b * 2 ^ 10b
이 가수의 반올림은 부동 소수점 값과 연관된 정밀도의 손실로 이어집니다. 가수가 정확하게 표현 될 수있는 경우에도 (예를 들어, 두 개의 숫자를 더할 때) 지수를 정규화 한 후 가수가 너무 많은 숫자를 필요로하는 경우 숫자 손실이 발생할 수 있습니다.
우리는 실제로 소수를 관리 가능한 크기로 반올림하고 처음 몇 자리 숫자를 줄 때 항상 이런 종류의 일을합니다. 결과를 십진수로 표현하기 때문에 자연 스럽습니다. 그러나 소수점을 반올림 한 다음 다른 기준으로 변환하면 부동 소수점 반올림으로 인해 발생하는 소수점과 같이보기 흉하게 보일 것입니다.