왜 십진수를 이진수로 정확하게 표현할 수 없습니까?


284

부동 소수점 표현에 관해 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 ...

이 숫자에는 임의의 제한이 없습니다. 위치는 왼쪽과 오른쪽으로 무한정 증가합니다.


2
부동 소수점 nubmber 내에서 무슨 일이 일어나고 있는지 정확하게 이해하는 데 도움이 될 수 있습니다 . 부동 소수점 수의 해부학 .
John D. Cook

57
이진수로 숫자 3은 2¹ + 2 ° = 2 + 1로 표시됩니다. 좋고 쉬운. 이제 1/3을보십시오. 2의 음의 거듭 제곱을 사용하여 어떻게 표현할 수 있습니까? 조금 실험 해 보면 1/3은 무한 시퀀스 2 ^ -2 + 2 ^ -4 + 2 ^ -6 + 2 ^ -8 + ...의 합과 같습니다. 이진수로 정확하게 표현하기 쉽지 않습니다.
Lars Haugseth

21
Jon Skeet은 몸의 질문에 아주 잘 대답합니다. 한 가지 빠진 것은 실제로 두 가지 다른 질문을한다는 것입니다. 제목 문제는 "이진수로 정확히 십진수를 표현할 수없는 이유는 무엇입니까?"입니다. 대답은 그들이 할 수 있다는 것입니다. 제목과 본문 사이에 "이진"이라는 아이디어와 "부동 소수점 표현"이라는 아이디어를 혼동합니다. 부동 소수점은 정밀도를 희생하여 고정 된 2 진수 숫자로 10 진수를 표현하는 방법입니다. 이진수는 계산에 대한 다른 기준일 뿐이며 무한 자릿수를 지정하면 소수 자릿수를 나타낼 수 있습니다.
Chris Blackwell

3
정확한 십진법을 나타내는 몇 가지 시스템이 있습니다. 그것은 당신이 묘사 한 것처럼 거의 작동합니다. SQL 10 진수 유형이 한 예입니다. LISP 언어가 내장되어 있습니다. 정확한 십진법 계산을위한 여러 상용 및 오픈 소스 라이브러리가 있습니다. 이것에 대한 하드웨어 지원이 없으며 단지 대부분의 언어와 하드웨어가 32 또는 64 비트의 무한한 숫자를 나타내는 IEEE 표준을 구현합니다.
nos

1
은 (는 관련 수학 프로그램에도 경우) 수학에 관한 더 나은에 일 것이기 때문에이 질문은 주제 꺼져있는 것처럼 보이 수학
콜 존슨

답변:


360

부동 이진수 점 숫자가 아닌 충분한 공간이 있으면 십진수를 정확하게 나타낼 있습니다 . 부동 소수점 유형 (예 : .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을 표현할 수 없습니다. 다른 방법으로 라운드와 비교하십시오 : 임의의 소수 자릿수가 주어지면 부동 이진수로 정확하게 표현할 수있는 모든 숫자를 정확하게 나타낼 수 있습니다 .


8
정말 훌륭한 예입니다!
Tom Ritter

5
... 이걸 두 번 공표 할 수 있습니다. 나는 이것에 대해 너무 많은 질문을 받았다. 사람들이 기본 10 밖에서 생각할 수없는 것과 거의 같습니다. hehe
Justin Niessner

38
예, 세상에는 바이너리를 이해하는 사람들과 모르는 사람들이 10 가지 있습니다.
duffymo

83
@ JonSkeet : 두 손가락으로 Ctrl + Alt + Delete 가 어색해 보입니다.
Lars Haugseth

20
@muusbolla : 아니요. 소수점 표시 1와 소수점 표시 0.9...( 소수점 다음에 무한 반복 9s)로 표시되는 숫자는 같습니다. 아마도 가장 쉬운 방법은 다음과 같습니다. Let x = 0.9.... 참고하십시오 10x = 9.9..... 따라서 9x = 10x - x = 9.9... - 0.9... = 9되도록 9x = 9하고 x = 1. 이것을 볼 수있는 다른 방법이 있지만, 이것이 가장 간단하다고 생각합니다.
제이슨

25

예를 들어, 숫자 61.0은 숫자의 정수 부분이 항상 정확하기 때문에 정확한 이진 표현을 갖습니다. 그러나 숫자 6.10은 정확하지 않습니다. 내가 한 것은 소수를 한 자리로 옮기는 것인데 갑자기 Exactopia에서 Inexactville로 갔다. 수학적으로 두 숫자 사이에는 본질적인 차이가 없어야합니다 . 단지 숫자 일뿐입니다 .

베이스 10과 2의 세부 사항에서 잠시 벗어나 보자.베이스를 물어보고 b, 어떤 숫자로 끝나는 표현이 있고, 어떤 숫자가 그렇지 않은가? 잠시 생각 하면 정수 와 같은 정수가있는 경우에만 숫자 x에 종결 표시 가 있음을 알 수 있습니다 .bnx b^n

예를 들어 정수를 선택한 다음을 x = 11/500선택할 수 있기 때문에 종료 10 표현이 있습니다 . 그러나 우리가 선택한 것이 무엇이든 우리는 3을 제거 할 수 없기 때문에 그렇지 않습니다 .n = 3x b^n = 22x = 1/3n

이 두 번째 예는 요인에 대해 생각하도록 촉구하며, 합리적 x = p/q (가장 낮은 용어로 가정)에 대해 b와 의 소인수 분해를 비교하여 질문에 대답 할 수 있음을 알 수 있습니다 q. 경우 q하지의 주요 인수 분해의 모든 주요 요소를 가지고 b, 우리는 적절한 찾을 수 없을 것입니다 n이러한 요소를 제거 할 수 있습니다.

따라서 기수 10의 경우 2 또는 5 이외의 주요 요소가 있는 p/qq은 종료 표현이 없습니다.

이제 10 번 기지와 2 번 기지로 되돌아 가면, 10 번 표현이 끝나는 모든 합리적 요소가 1 차 분해에 s와 s 만 p/q있을 때 의 형태가 될 것입니다 . 그리고 같은 수는 소인수 분해 만 있을 때 정확하게 2 차 종료를 나타냅니다 .q25q2

그러나 이러한 경우 중 하나는 다른 하나의 일부입니다. 할때는 언제나

q이 단지 2의 주요 인수 분해에이야

그것은 또한 사실이다

q소인수 분해에서 2s와 5s 만 있음

또는 다른 방법으로, 종료 2 표현이 있을 때마다 종료 10 표현이p/qp/q 있습니다. 반대의 그러나 않습니다 하지 개최 - 때마다 q그 주요 인수 분해에 5를 가지고, 그것은 종료 10 표현하지만 것 없는 종단이-표현을. 이것은 0.1다른 답변에서 언급 한 예입니다.

따라서 2의 소인수는 10의 소인수의 부분 집합이므로 모든 2 개의 종료하는 숫자는 10 개의 종료하는 숫자이지만 그 반대도 아닙니다. 약 61 대 6.1이 아니며 약 10 대 2입니다.

기부 (5) 사용되는 몇 가지 특질을 사용하는 사람 (말) 기본 17 그러나 우리의 컴퓨터에서, 당신의 직관이에 의해 타락 주도되지 못했을 경우 닫는 참고로, - 없을 것이다 아무 종료 (0이 아닌 정수가 아닌) 번호 두 경우 모두!


그렇다면 왜 "alert (0.15 * 0.15)"에 "0.0225"가 표시됩니까?
Michael Geiser

5
@MichaelGeiser 짧은 답변 : 표시 지점에서 반올림. 당신이 생각하는 0.15것은 실제로 (IEEE double로 저장 될 때)`0.149999999999999994448884876874`입니다. jsfiddle을 참조하십시오 .
AakashM

포인트 코드 예제가 명확합니다! 나는 당신에게 그것에 대한 투표를 줄 수 있기를 바랍니다! 반올림이 발생하는 위치를 탐색하려면 몇 가지 기능을 사용해야합니다. 나는 우리가 실제로이 쓰레기를 처리해야한다는 것에 놀랐습니다. 사람들은 기본적으로 거의 100 %의 시간을 작업하고 우리는 정수가 아닌 시간을 너무 많이 사용하므로 부동 소수점 수학의 기본 구현이이 말도 안될 것이라고 생각할 것입니다.
Michael Geiser

1
@MichaelGeiser베이스 2로 작동하는 회로는베이스 10으로 작동하는 회로보다 작고 빠르며 전력 효율이 높습니다. 오늘날 우리는 오버 헤드를 정당화 할 수 있지만 표준이 설정된 1970 년대에는 큰 거래. 프로세서 회로를 직접 지원하지 않고 그것을 시도하는 것은 훨씬 더 나쁘다. 속도 차이가 크다.
Mark Ransom

이 답변은 Jon Skeet 자신보다 더 잘 설명합니다!
goelakash

16

근본 (수학적) 이유는 정수를 처리 할 때 그 수가 무한히 많기 때문 입니다.

즉, 무한한 양이 있더라도 순서의 모든 항목을 건너 뛰지 않고 "계산"할 수 있습니다. 즉 610000000000000, 목록에서 세 번째 위치에 항목을 가져 오려면 수식을 통해 항목을 파악할 수 있습니다.

그러나 실수는 셀 수없이 무한 합니다. 당신은 "위치에 실제 숫자를 줘"라고 말하고 610000000000000답을 얻을 수 없습니다 . 부동 소수점 값을 고려할 때 0및 사이에도 1무한 수의 값 이 있기 때문 입니다. 두 개의 부동 소수점 숫자에 대해서도 마찬가지입니다.

더 많은 정보:

http://en.wikipedia.org/wiki/Countable_set

http://en.wikipedia.org/wiki/Uncountable_set

업데이트 : 사과합니다. 질문을 잘못 해석 한 것 같습니다. 내 대답은 왜 우리가 모든 실제 가치를 대표 할 수 없는지에 관한 것입니다 . 나는 부동 소수점이 자동으로 합리적으로 분류된다는 것을 깨닫지 못했습니다.


6
실제로 유리수 셀 수없이 무한합니다. 그러나 모든 실수 가 합리적인 숫자는 아닙니다 . 나는 확실히 당신이 결국 내게주고 싶은 정확한 10 진수에 도달하는 정확한 10 진수 시퀀스를 생성 할 수 있습니다. 비합리적인 숫자 를 다룰 필요가 있고 셀 수없이 무한한 세트를 만들어야하는 경우입니다.
Jon Skeet

사실, 나는 "부동 소수점"이 아니라 "진짜"라고 말해야합니다. 명확히합니다.
TM.

1
IMO는 이진 부동 소수점을 사용하여 모든 실수를 처리 할 수있을뿐만 아니라 모든 합리적인 숫자 (예 : 0.1) 도 처리 할 수 없기 때문에 로직이 적용되지 않는 시점이 됩니다. 다시 말해서, 나는 그것이 실제로 계산과 전혀 관련이 없다고 생각합니다 :)
Jon Skeet

@ jonskeet 나는 Jon Skeet에 동의하지 않으면 자연의 기본 법칙을 어길 것이라고 알고 있습니다. 물론 그렇게하지는 않을 것입니다. 외부 적으로 나타내려는 값 세트. 생각이 라인을 사용하면 인덱스의 목록은 (당신이 정밀의 말, 무한 비트를했다해도) 얼마나 큰 상관없이, 당신은 것을 볼 수 있습니다 여전히 모두에게 실수를 표현 할 수 없습니다.
TM.

3
@TM : 그러나 OP는 모든 실수를 나타내려고하지 않습니다. 그는 모든 정확한 십진수 를 나타내려고 노력하는데 , 이는 합리적인 숫자 의 하위 집합 이므로 셀 수없이 무한합니다. 그가 부동 소수점 유형으로 무한 비트 세트를 사용 하고 있다면 괜찮을 것입니다. 이 비트를 이진 부동 소수점 유형 으로 사용하여 십진수에 문제가 발생합니다.
Jon Skeet

10

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 .

표현 시스템에 기호를 추가 할 수 없다고하는 것은 아무것도 없으므로, 이진 따옴표 표기법을 사용하여 정확히 십진수를 표현할 수 있으며 그 반대도 마찬가지입니다.


사이클이 시작되고 끝나는 위치를 알고 있으면 해당 표기법 시스템이 작동합니다. 인간은주기를 감지하는 데 능숙합니다. 그러나 일반적으로 컴퓨터는 그렇지 않습니다. 반복 기호를 효과적으로 사용하려면 컴퓨터에서 계산 후 사이클의 위치를 ​​파악할 수 있어야합니다. 예를 들어 숫자 1/3의 경우 사이클이 바로 시작됩니다. 그러나 숫자 1/97의 경우 최소 96 자리에 대한 답을 구할 때까지주기가 표시되지 않습니다. (실제로, 당신은 확실히 96 * 2 + 1 = 193 자리가 필요합니다.)
Barry Brown

4
실제로 컴퓨터가주기를 감지하는 것은 결코 어렵지 않습니다. Hehner의 논문을 읽으면 다양한 산술 연산의주기를 감지하는 방법에 대해 설명합니다. 예를 들어, 반복 빼기를 사용하는 나눗셈 알고리즘에서는 이전에 본 차이를 볼 때주기가 시작되는 위치를 알 수 있습니다.
ntownsend

3
또한 문제는 숫자를 정확하게 나타내는 것에 관한 것입니다. 때로는 정확한 표현은 많은 비트를 의미합니다. 인용구 표기법의 장점은 Hehner가 표준 32 비트 고정 길이 표현에 비해 표현 크기가 평균 31 % 절약된다는 것을 보여줍니다.
ntownsend

6

BCD- 이진 코드 10 진수 -표현이 정확합니다. 그것들은 공간 효율적이지는 않지만,이 경우 정확성을 위해해야 ​​할 절충점입니다.


1
BCD는 다른베이스보다 정확하지 않습니다. 예 : BCD에서 1/3을 어떻게 정확하게 표현합니까? 당신은 할 수 없습니다.
Jörg W Mittag

12
BCD는 DECIMAL의 정확한 표현이므로 이름의 "소수"부분입니다. 1/3의 정확한 십진수 표현도 없습니다.
Alan

4

기초 10에서 1/3을 정확하게 표현할 수없는 것과 같은 이유로 0.33333 (3)을 말해야합니다. 이진에서는 같은 유형의 문제이지만 다른 숫자 집합에 대해서만 발생합니다.


4

(참고 : 여기에 이진수를 나타 내기 위해 '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

이 가수의 반올림은 부동 소수점 값과 연관된 정밀도의 손실로 이어집니다. 가수가 정확하게 표현 될 수있는 경우에도 (예를 들어, 두 개의 숫자를 더할 때) 지수를 정규화 한 후 가수가 너무 많은 숫자를 필요로하는 경우 숫자 손실이 발생할 수 있습니다.

우리는 실제로 소수를 관리 가능한 크기로 반올림하고 처음 몇 자리 숫자를 줄 때 항상 이런 종류의 일을합니다. 결과를 십진수로 표현하기 때문에 자연 스럽습니다. 그러나 소수점을 반올림 한 다음 다른 기준으로 변환하면 부동 소수점 반올림으로 인해 발생하는 소수점과 같이보기 흉하게 보일 것입니다.


4

좋은 질문입니다.

귀하의 모든 질문은 "우리는 어떻게 숫자를 대표합니까?"

모든 숫자는 10 진수 표현 또는 2 진수 (2의 보수) 표현으로 표현할 수 있습니다. 그들 모두 !!

그러나 일부 (대부분의 경우)에는 무한한 수의 요소가 필요합니다 (이진 위치의 경우 "0"또는 "1", 10 진수 표시의 경우 "0", "1"~ "9").

소수점 이하 1/3 (1/3 = 0.3333333 ... <-- "3"의 무한 수)

이진수로 0.1과 같이 (0.1 = 0.00011001100110011 .... <-는 무한한 "0011")

모든 것이 그 개념에 있습니다. 컴퓨터는 유한 자릿수 (십진수 또는 이진수) 만 고려할 수 있으므로 일부 숫자 만 컴퓨터에서 정확하게 표현할 수 있습니다 ...

Jon이 말했듯이 3은 10의 인수가 아닌 소수이므로 1/3은 10의 유한 요소 로 표현할 수 없습니다 .

임의의 정밀도로 산술을 사용하더라도 밑면 2의 번호 매기기 위치 시스템은 6.1을 완전히 설명 할 수는 없지만 61을 나타낼 수는 있습니다.

6.1의 경우 다른 표현을 사용해야합니다 (소수점 표현 또는 부동 소수점 값을 표현하기 위해 밑이 2 또는 밑이 10 인 IEEE 854).


1/3을 분수 자체로 나타낼 수 있습니다. 그것을 나타 내기 위해 무한한 양의 비트가 필요하지 않습니다. 1을 취해서 3으로 나눈 결과 대신 1/3을 분수로 표현하면됩니다. 여러 시스템이 그렇게 작동합니다. 그런 다음 표준 / * + 및 유사한 연산자를 사용하여 분수 표현을 수행하는 방법이 필요하지만 매우 쉽습니다. 펜과 종이로 이러한 작업을 수행 할 수 있습니다. .
nos

나는 "이진 (2의 보수) 표현"에 대해 이야기하고있었습니다. 물론 다른 표현을 사용하면 유한 요소 수로 숫자 를 표현 하는 데 도움이 될 수 있습니다 (다른 요소에는 무한 수의 요소가 필요함)
ThibThib

3

부동 소수점을 사용하여 충분히 큰 수를 만들면 (소수점을 사용할 수 있음) 소수점 앞에도 부정확하게 표시됩니다. 따라서 전제가 잘못되어 귀하의 질문이 전적으로 타당하다고 생각하지 않습니다. 어떤 점에서 부동 소수점 숫자는 지수를 사용하여 숫자의 큰 숫자를 나타내야하며 정밀도도 떨어질 수 있기 때문에 10만큼 시프트하면 항상 더 정밀한 경우가 아닙니다.


3

아무도 이것을 아직 언급하지 않은 것에 놀랐습니다 . 계속 분수를 사용하십시오 . 이런 식으로 임의의 합리적인 숫자를 이진수로 유한하게 나타낼 수 있습니다.

몇 가지 예 :

1/3 (0.3333 ...)

0; 3

5/9 (0.5555 ...)

0; 1, 1, 4

10/43 (0.232558139534883720930 ...)

0; 4, 3, 3

9093/18478 (0.49209871198181621387596060179673 ...)

0; 2, 31, 7, 8, 5

여기에는 일련의 정수를 메모리에 저장하는 다양한 알려진 방법이 있습니다.

완벽한 정확도로 숫자를 저장하는 것 외에도 연속 분수는 최고의 합리적인 근사와 같은 다른 이점도 있습니다. 연속 분수에서 숫자 시퀀스를 조기에 종료하기로 결정한 경우, 나머지 숫자 (분수로 재결합 할 때)는 최상의 분수를 제공합니다. 이것은 pi에 대한 근사치를 찾는 방법입니다.

Pi의 계속되는 분수 :

3; 7, 15, 1, 292 ...

1에서 시퀀스를 종료하면 분수가 표시됩니다.

355/113

이것은 합리적인 합리적인 근사치입니다.


하지만 어떻게 이진법으로 표현할까요? 예를 들어 15는 4 비트가 필요하지만 292는 9가 필요합니다. 하드웨어 (또는 소프트웨어)는 비트 경계가 각각의 위치를 ​​어떻게 알 수 있습니까? 효율성 대 정확성 트레이드 오프입니다.
열렬한

2

방정식에서

2^x = y ;  
x = log(y) / log(2)

따라서 바이너리에 대한 로그 기반 시스템을 사용할 수 있는지 궁금합니다.

 2^1, 2^0, 2^(log(1/2) / log(2)), 2^(log(1/4) / log(2)), 2^(log(1/8) / log(2)),2^(log(1/16) / log(2)) ........

문제를 해결할 수 있으므로 32.41과 같은 바이너리를 바이너리로 쓰려면

2^5 + 2^(log(0.4) / log(2)) + 2^(log(0.01) / log(2))

또는

2^5 + 2^(log(0.41) / log(2))

1

문제는 실제로 숫자가 정확히 61.0인지 여부를 실제로 알 수 없다는 것입니다. 이걸 고려하세요:


float a = 60;
float b = 0.1;
float c = a + b * 10;

c의 가치는 무엇입니까? .1에 정확한 이진 표현이 없기 때문에 b가 실제로 .1이 아니기 때문에 정확히 61이 아닙니다.


1

숫자의 의미가 정수에서 정수가 아닌 것으로 바뀌 었으므로 임계 값이 있습니다. 61을 나타 내기 위해 6 * 10 ^ 1 + 1 * 10 ^ 0; 10 ^ 1과 10 ^ 0은 모두 정수입니다. 6.1은 6 * 10 ^ 0 + 1 * 10 ^ -1이지만 10 ^ -1은 1/10이며 이는 정수가 아닙니다. 이것이 당신이 Inexactville에서 끝나는 방법입니다.


1

분수와 정수로 병렬을 만들 수 있습니다. 1/7과 같은 일부 분수는 로트와 로트가 없으면 10 진수 형식으로 표현할 수 없습니다. 부동 소수점은 이진 기반이므로 특수한 경우가 변경되지만 동일한 정확도 문제가 발생합니다.


0

무한 수의 유리수와 그것들을 나타내는 유한 수의 비트가 있습니다. http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems를 참조하십시오 .


그러나 무한한 비트 수의 경우에도 부동 이진 점 을 사용 하면 무한한 비트 수로도 정확히 10 진수로 1/3을 표현할 수없는 것처럼 0.1을 정확하게 표현할 수 없습니다.
Jon Skeet

3
@Jon 그건 사실이 아닙니다 : 무한 의 소수로, 예를 들어 '1/3'을 정확하게 표현할 수 있습니다 . 실제 문제는 물리적으로 "무한 수"의 소수 또는 비트를 가질 수 없다는 것 입니다.
ChrisW

0

숫자 61.0은 실제로 정확한 부동 소수점 연산을 갖지만 모든 정수에 해당되는 것은 아닙니다 . 배정 밀도 부동 소수점 숫자와 64 비트 정수 모두에 1을 추가 한 루프를 작성했다면 결국 64 비트 정수가 숫자를 완벽하게 나타내는 지점에 도달하지만 부동 소수점은 그렇지 않습니다 — 유효 비트가 충분하지 않기 때문입니다.

소수점 오른쪽의 근사 점에 도달하는 것이 훨씬 쉽습니다. 이진 부동 소수점으로 모든 숫자를 쓰기 시작하면 더 의미가 있습니다.

그것에 대해 생각하는 또 다른 방법은 61.0이 밑 10에서 완벽하게 표현 가능하다는 것을 알았을 때 소수점을 이동해도 그 변화가 바뀌지 않으면 10의 거듭 제곱으로 곱셈을 수행한다는 것입니다 (10 ^ 1, 10 ^ -1 ). 부동 소수점에서 2의 거듭 제곱은 숫자의 정밀도에 영향을 미치지 않습니다. 완벽하게 정확한 숫자가 정확한 표현을 잃을 수있는 방법을 설명하기 위해 61.0을 취하고 그것을 3으로 반복해서 나누어보십시오.


0

정수를 알고 있습니까? 각 비트는 2 ^ n을 나타냅니다.


2 ^ 4 = 16
2 ^ 3 = 8
2 ^ 2 = 4
2 ^ 1 = 2
2 ^ 0 = 1

잘 부동 소수점 (일부 구별)과 동일하지만 비트는 2 ^ -n 2 ^ -1 = 1 / 2 = 0.5
2 ^ -2 = 1 / (2 * 2) = 0.25
2 ^ -3 = 0.125를 나타냅니다.
2 ^ -4 = 0.0625

부동 소수점 이진 표현 :

지수 분수 (나는 보이지 않는 1이 분수에 첨부
된다고 생각한다) B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0


0

위의 높은 점수 답변이 그것을 못 박았습니다.

먼저 당신은 당신의 질문에베이스 2와베이스 10을 혼합하고 있었고, 당신이베이스에 나눌 수없는 숫자를 오른쪽에 넣으면 문제가 발생합니다. 3은 2의 거듭 제곱이 아닌 2의 10 또는 1/5의 거듭 제곱으로 들어 가지 않기 때문에 10 진수 1/3과 같습니다.

다른 주석은 부동 소수점 숫자, 마침표와 동일하게 사용하지 마십시오. 정확한 표현이더라도 일부 부동 소수점 시스템에는 여러 가지 방법으로 정확하게 표현할 수있는 숫자가 있습니다 (IEEE는 이것에 대해 나쁜 점으로 시작하므로 끔찍한 부동 소수점 사양이므로 두통을 예상하십시오). 소수점 오른쪽에 3이 몇 개 있더라도 1/3은 계산기 0.3333333의 숫자와 같지 않습니다. 충분히 가깝거나 같을 수는 없습니다. 반올림에 따라 2 * 1 / 3와 같은 것이 2/3와 같지 않을 것으로 예상합니다. 부동 소수점과 동일하게 사용하지 마십시오.


0

우리가 논의했듯이, 부동 소수점 산술에서 십진수 0.1은 이진수로 완벽하게 표현 될 수 없습니다.

부동 소수점 및 정수 표현은 표시된 숫자에 대한 격자 또는 격자를 제공합니다. 산술이 완료되면 결과가 그리드에서 떨어지고 반올림하여 그리드에 다시 넣어야합니다. 이진 그리드의 예는 1/10입니다.

한 신사가 제안한 것처럼 이진 코드 십진수 표현을 사용하면 그리드에 숫자를 유지할 수 있습니까?


1
십진수입니다. 그러나 그것은 단지 정의에 의한 것입니다. 십진수로 1/3을 표현할 수 없으며, 이진수로 0.1을 표현할 수있는 것 이상입니다. 무한대로 큰 숫자 집합에 대해서는 양자화 체계가 실패합니다.
Kylotan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.