왜 컴퓨터가 10 진수를 두 번째 정수로 저장하지 않습니까?


24

컴퓨터는 분모가 2 ^ x에 대한 해답이 아닌 다른 소수를 저장하는 데 문제가 있습니다. 소수점 이하의 첫 번째 숫자는 1/2, 두 번째 1/4 (또는 1 / (2 ^ 1) 및 1 / (2 ^ 2)) 등의 가치가 있기 때문입니다.

컴퓨터가 숫자의 소수 부분을 다른 정수로 저장했을 때 모든 종류의 반올림 오류를 처리하는 이유는 무엇입니까?

내가 생각할 수있는 유일한 것은 (소수점 10에서) 반복되는 소수점을 다루는 것이지만 (우리가 현재 무한대로 가지고있는 것처럼) 그것에 대한 해결책이있을 수 있습니다.


8
float / double 유형과 달리 10 진수 유형이 저장되는 방법을 찾아야합니다.
Oded

9
그것이 더 정확한지 모른다. 소수점 이하의 첫 번째 숫자는 1/10과 두 번째 1/100 등입니다. 더 정확한 반올림 문제는 어떻게 발생합니까 (1/3을 어떻게 표현합니까)? 유일한 차이점은 정확히 표현할 수있는 값입니다.
Martin York

17
십진 부동 소수점 (더 이상 어색한 표현으로 두 가지를 참조하는 것)은 이진 부동 소수점보다 정확하지 않습니다. 유일한 차이점은 어떤 값을 표현할 수 없는가에 대한 것이며, 우리는 십진법에 익숙하기 때문에 십진법의 오류를 눈치 채지 못합니다. 그리고 모든 합리적이거나 비합리적인 숫자를 대표 할 수는 없습니다.

1
하루가 끝나면 효율성으로 떨어집니다. 컴퓨터는 이진이며이 이진 표현으로 작동하는 회로는 훨씬 덜 복잡합니다. 이것의 중요성은 오늘날 다소 줄어들 수 있지만, 이것이 매우 중요한 시대였습니다. 또한 컴퓨터에 숫자를 유한 공간에 저장하기로 선택한 표현에는 유한 값 세트가 있으며 모든 입력에 반올림 오류가 표시됩니다. Mantissa 및 Exponent의 일반적인 부동 소수점 형식은 훨씬 큰 범위를 제공하며 두 정수를 사용하여 가능합니다.
Mr.Mindor

1
부동 소수점 반올림 오류의 원인은 무엇입니까?에 대한 답변 에서 참조 된 기사 중 일부를 읽는 것이 좋습니다 . 참조 시리즈의 마지막 기사에 대한 세부 정보로 방금 업데이트했습니다. 특히 고정 소수점이 부동 소수점 파란색을 치료하지 않는 이유를 살펴보십시오 .
Mark Booth

답변:


35

실제로는 숫자 모드가 있습니다.

이진 코드 10 진수 (BCD) 산술은 기본 10에서 컴퓨터 작업을 수행합니다.이 문제가 발생하는 이유는 거의 공간을 낭비하지 않기 때문입니다. 숫자의 각 개별 숫자는 최소 4 비트를 차지하지만 컴퓨터는 해당 공간에 16 개의 값이 있습니다. 또한 속도가 느려질 수 있지만 하드웨어 가속 BCD 수학을 사용하는 것이 가능합니다. 사실 이것은 대부분의 계산기가하는 일이므로 데스크탑 컴퓨터에서 점심을 먹을 수있는 5 달러짜리 카시오에서는 절대로 발생하지 않는 반올림 문제가 있습니다.

취할 수있는 다른 경로는 유리수, 즉 분자와 분모를 정수로 저장하는 것입니다. 이것은 실제로 거의 모든 언어로 제공되며 정확하며 모든 것을 기본 이진 형식으로 저장할 수 있습니다. 문제는 하루가 끝날 때 사용자가 463/13 또는 35 및 8/13과 같은 분수를보고 싶지 않다는 것입니다. 그들은 35.615를보고 싶어합니다. 그리고 당신이 도착하는 순간, 당신은 모든 전형적인 문제에 직면합니다. 이 형식은 더 많은 공간을 차지 하며 부동 소수점 산술보다 상당히 느릴 수 있으며 기본적으로이 형식을 사용하는 컴퓨터는 없습니다.

따라서 컴퓨터는 원하는 것을 수행 할 수 있지만 속도가 느리고 공간을 낭비하므로 실제로 필요할 때만 수행합니다. 나머지 시간, 부동 소수점의 속도 및 공간 절약은 더 나은 절충점입니다.


BCD 단락에서 4 비트 (바이트가 아님) 를 의미하지 않습니까?

3
다른 옵션은 고정 소수점 산술입니다. 여기서 정수는 숫자 인 경우 소수점 이하 자릿수를 나타냅니다. 예를 들어, 돈 값 저장 (소수 또는 백분율 관련 계산없이) 1은 $ 0.01을 나타냅니다.
mattnz

1
@mattnz : 참 — 고정 점은 합리적 특수 사례입니다.
Jon Purdy

굉장합니다, 계산기가 그렇게했는지 몰랐습니다.
SomeKittens

3
세 번째 옵션이 있습니다. C # decimal을 구현 하는 방법과 같이 소수 지수가있는 부동 소수점 : stackoverflow.com/a/5019178/174335 소수의 개별 표현이 없으므로 고정 소수점이 아니기 때문에 BCD가 아닙니다.
Joren

38

소수를 저장하는 방법은 여러 가지가 있으며 각 방법에는 장단점이 있습니다.

부동 소수점 은 가장 널리 사용되는 형식입니다. 부호, 가수 및 부호있는 기수 2 지수를 정수로 인코딩하고 비트로 묶음으로써 작동합니다. 예를 들어 32 비트 가수 0.5(로 인코딩 됨 0x88888888)와 32 비트 부호있는 지수 +3( 0x00000003)를 4.0(0.5 * 2 ^ 3). 부동 소수점 숫자는 하드웨어에서 구현되기 때문에 빠르며, 절대 크기의 정밀도 스케일, 즉 숫자가 작을수록 절대 정밀도가 좋아 지므로 상대 반올림 오류는 절대 크기로 일정하게 유지됩니다. 플로트는 길이, 음압 레벨, 광 레벨 등과 같은 연속 영역에서 샘플링 된 값에 탁월하며, 이로 인해 통계 분석 및 물리 시뮬레이션뿐만 아니라 오디오 및 이미지 처리에 일반적으로 사용됩니다. 가장 큰 단점은 정확하지 않다는 것, 즉 반올림 오류가 발생하기 쉽고 모든 소수를 정확하게 표현할 수 없다는 것입니다. 모든 주류 프로그래밍 언어에는 일종의 부동 소수점이 있습니다.

고정 소수점충분히 큰 정수를 사용하고 소수 부분에 대해 비트의 일부를 암시 적으로 예약하여 작동합니다. 예를 들어, 24.8 비트 고정 소수점 수는 정수 부분 (부호 포함)에 24 비트, 소수 부분에 8 비트를 예약합니다. 이 숫자를 8 비트로 오른쪽 이동하면 정수 부분이됩니다. 고정 소수점 숫자는 하드웨어 부동 소수점 단위가 일반적이지 않거나 정수의 정수보다 훨씬 느릴 때 널리 사용되었습니다. 고정 소수점 숫자는 정확성 측면에서 처리하기가 다소 쉽지만 (추론하기가 더 쉬운 경우에만) 다른 모든 측면에서 부동 소수점보다 열등합니다. 정밀도가 낮고 범위가 작으며 추가로 인해 암시 적 시프트에 대한 계산을 수정하려면 연산이 필요합니다. 오늘날 고정 소수점 수학은 종종 부동 소수점 수학보다 느립니다.

10 진수 유형은 부동 소수점 또는 고정 소수점 숫자와 매우 유사하지만 10 진수 시스템, 즉 지수 (암시 적 또는 명시 적)는 2의 거듭 제곱이 아니라 10의 거듭 제곱을 인코딩한다고 가정합니다. 예를 들어 10 진수는 가수 23456와 지수를 인코딩 -2할 수 있습니다.234.56. 십진수는 산술이 CPU에 하드 와이어로 연결되어 있지 않기 때문에 부동 소수점보다 느리지 만 소수를 포함하고 정확한 숫자가 필요한 모든 것에 이상적입니다. 반올림은 재정의 계산, 스코어 보드 등. 일부 프로그래밍 언어에는 10 진수 유형 (예 : C #)이 내장되어 있고 다른 언어에는이를 구현하기위한 라이브러리가 필요합니다. 소수는 반복되지 않는 소수를 정확하게 나타낼 수 있지만 정밀도는 부동 소수점 숫자보다 정확하지 않습니다. 소수를 선택한다는 것은 소수 시스템에서 정확하게 표현할 수있는 숫자를 정확하게 표현한다는 것을 의미합니다 (float가 이진 소수를 정확하게 나타낼 수있는 것처럼).

유리수 는 일반적으로 일종의 bignum 정수 유형 (컴퓨터의 메모리 제한 조건이 허용하는 한도에서 커질 수있는 숫자 유형)을 사용하여 분자와 분자를 저장합니다. 이것은 1/3또는 같은 숫자를 정확하게 모델링 할 수있는 유일한 데이터 유형이며 3/17다른 데이터 유형과 달리 합리적은 다음과 같은 것에 대한 올바른 결과를 생성합니다3 * 1/3. 효율적인 인수 분해 알고리즘을 생각해내는 것은 다소 어려운 일이지만 수학은 매우 간단합니다. 일부 프로그래밍 언어에는 합리적인 유형이 내장되어 있습니다 (예 : Common Lisp). 합리성의 단점은 느리거나 (많은 연산은 분수를 줄이고 구성 요소를 분해해야 함) 많은 일반적인 연산은 구현하기 어렵거나 불가능하며, 대부분의 구현은 이러한 상황이 발생할 때 플로트에 대한 합리성을 저하시킵니다 (예 : 호출 할 때) sin()합리적인).

BCD (Binary Coded Decimal)는 "니블"(4 비트 그룹)을 사용하여 개별 숫자를 인코딩합니다. 니블은 16 개의 서로 다른 값을 보유 할 수 있지만 10 진수는 10 개만 필요하므로 니블 당 6 개의 "잘못된"값이 있습니다. 소수점과 마찬가지로 BCD 숫자는 십진수로 정확합니다. 즉, 십진수에서 수행 된 계산은 펜과 종이를 사용했을 때와 같은 방식으로 작동합니다. BCD의 산술 규칙은 다소 어색하지만, 다른 형식보다 문자열로 변환하는 것이 더 쉽다는 장점이 있습니다. 이는 임베디드 시스템과 같은 저자 원 환경에 특히 흥미 롭습니다.

문자열 , 예, 평범한 오래된 문자열도 분수를 나타내는 데 사용할 수 있습니다. 기술적으로 이것은 BCD와 매우 유사하며 명시 적 소수점이 있고 소수점 이하 자릿수 하나만 사용한다는 점만 다릅니다. 따라서 형식은 낭비 적이지만 (256 개의 가능한 값 중 11 개만 사용됨) BCD보다 구문 분석 및 생성이 더 쉽습니다. 또한 사용 된 모든 값이 "의심스럽지 않고"무해하며 플랫폼 중립적이므로 문자열 인코딩 된 숫자는 문제없이 네트워크를 통해 이동할 수 있습니다. 산술이 문자열에서 직접 수행되는 것은 드문 일이지만 가능할 수 있으며 그렇게 할 때 다른 10 진수 형식 (10 진수 및 BCD)과 마찬가지로 정확히 10 진수입니다.


고정 소수점 표현에는 가수가 포함되지 않으므로 32 비트 고정 소수점은 32 비트 부동 소수점보다 정밀도가 더 높습니다.
han

4
@han : 저장하려는 숫자의 크기에 따라 다릅니다. 부동 소수점은 숫자가 크든 작든 상관없이 동일한 정밀도를 제공하지만 고정 점은 저장하려는 숫자가 해당 범위에 완벽하게 맞으면 정확도를 제공합니다.
Leo

@han 반드시 그런 것은 아니지만 둘 다 여전히 2 ^ 32 개의 고유 값을 나타낼 수 있습니다. 운반 정보의 양은 프리젠 테이션에 상관없이 동일합니다. 그러나 범위와 정밀도는 밀접한 관련이 있으므로 고정 소수점 산술은 특정 범위에서 더 정확할 수 있습니다. 작업 할 수있는 한계를 알고 있으면 불규칙한 반올림 문제가 발생하지 않습니다.
zxcdw

@ 한 : 그들은 같은 정밀도 (또는 거의)를 가지고 있습니다. 차이점은 고정 소수점 숫자의 경우 정수와 마찬가지로 이산 단계의 크기와 같이 정밀도는 정수와 마찬가지로 일정하지만 부동 소수점의 경우 절대 값으로 대략 선형으로 증가한다는 것입니다. 숫자 1.0은 숫자 10,000,000.0 (대략 백만 배 이상)보다 정밀도가 높습니다.
tdammers

6

부동 소수점 숫자는 광범위한 값을 나타내므로 값이 무엇인지 미리 알지 못하지만 타협 할 때 매우 유용합니다. 두 번째 정수로 1 / 10 ^ 100을 나타내는 것은 작동하지 않습니다.

일부 언어 (및 일부 라이브러리)에는 다른 특성이 있습니다. Lisp에는 전통적으로 무한 정밀 정수가 있습니다. 코볼은 고정 소수점 10 진수로 계산합니다.

문제 영역에 적합한 숫자 표현을 선택해야합니다.


1

고정 소수점 숫자를 설명하는 것처럼 들립니다 .

숫자의 소수 부분을 별도의 위치에 저장하는 것은 단일 공간을 두 배로 생성하고 전체 및 분수 부분을 두 개의 개별 반쪽에 저장하는 것과 정확히 동일합니다. 즉, 숫자를 정수로 저장하는 것과 동일하지만 고정 된 소수의 소수 공백을 가정합니다.

일반적으로 부동 소수점 숫자는 과학적 표기법의 이진 변형을 사용하여 저장됩니다. 일반적으로 중요한 것은 유효 숫자이기 때문입니다. 많은 다른 방법들이 존재합니다. 고정 소수점 10 진수는 일반적으로 통화 값을 저장하는 데 사용됩니다. 여기서 소수점 이하 자릿수까지 정확도가 중요하지만 필요한 소수 자릿수는 변경되지 않습니다.


1

그것은 BCD라고 할 것입니다. 정말로 원한다면 여전히 사용할 수 있다고 생각합니다. 그러나 실제로 다음과 같이 가치가 없습니다.

  1. 64 비트 부동 소수점으로 반올림 오류가 거의 발생하지 않습니다.
  2. 그것은 산술을 복잡하고 비효율적으로 만듭니다.
  3. 4 비트마다 6 개의 값을 낭비합니다

BCD 수학은 초기 8 비트 마이크로 프로세서 시스템에서 많이 사용되었습니다. 실제로, 하나의 널리 사용되는 마이크로 프로세서 (6502)에서 BCD의 덧셈과 뺄셈은 이진과 마찬가지로 바이트 당 빠릅니다. 비디오 게임은 종종 점수 유지에 BCD 수학을 사용했습니다. 1,000,000 포인트로 줄 바꿈되는 점수에는 특별한 처리가 없습니다. 대신 "99 99 99"에 1을 추가하면 캐리가 무시되고 "00 00 00"이 생성됩니다. BCD에서 점수를 추가하는 추가 오버 헤드는 이진 값을 표시 가능한 형식으로 변환하는 비용과 비교할 때 아주 작습니다.
supercat

1

짧은 대답은 부동 소수점이 과학적 계산을 위해 설계되었다는 것입니다. 그것은 대부분의 과학적 계산에서 정밀도가 측정되는 방식과 밀접하게 일치하는 지정된 유효 자릿수를 가진 숫자를 저장할 수 있습니다.

과학적 계산이 하드웨어 지원에서 가장 큰 이점을 얻는 경향이 있기 때문에 하드웨어에서 주로 지원되는 경향이 있습니다. 예를 들어, 재무 계산은 종종 다른 형식으로 수행되지만 재무 소프트웨어는 일반적으로 필요한 형식이 소프트웨어에서만 지원되지만 성능은 대부분의 재무 소프트웨어에 완벽하게 적합하다는 실제 계산을 거의 수행하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.