4배정밀도 부동소수점수

컴퓨팅에서 **4배정밀도** 또는 **쿼드러플 프리시전**(quadruple precision)은 16바이트(128비트)를 차지하는 이진 부동소수점 기반 컴퓨터 숫자 형식으로, 53비트 배정밀도의 두 배 이상의 정밀도를 가진다.

이 128비트 4배정밀도는 배정밀도 이상의 결과가 필요한 응용 프로그램뿐만 아니라 중간 계산 및 스크래치 변수에서 오버플로 및 반올림 오차를 최소화하여 배정밀도 결과를 보다 안정적이고 정확하게 계산할 수 있도록 하는 주요 기능도 수행한다. 원래 IEEE 754 부동소수점 표준의 주요 설계자였던 윌리엄 카한은 다음과 같이 언급했다. "현재 10바이트 확장 형식은 추가 정밀도 산술의 가치와 이를 빠르게 구현하는 비용 사이에서 적절한 절충안이다. 곧 두 바이트의 정밀도가 더 허용될 것이며, 궁극적으로는 16바이트 형식... IEEE 부동소수점 산술 표준 754가 제정될 때 이미 더 넓은 정밀도로의 점진적인 진화가 예상되었다."

IEEE 754-2008에서 128비트 2진 형식은 공식적으로 **binary128**이라고 불린다.

## IEEE 754 4배정밀도 이진 부동소수점 형식: binary128
IEEE 754 표준은 **binary128**을 다음과 같이 지정한다.

* 부호 비트: 1비트
* 지수 폭: 15비트
* 유효숫자 정밀도: 113비트 (112비트 명시적으로 저장)

부호 비트는 숫자의 부호를 결정한다(숫자가 0인 경우에도 부호가 있는 경우 포함). "1"은 음수를 나타낸다.

이것은 33에서 36개의 유효 십진수 정밀도를 제공한다. 최대 33개의 유효 십진수를 가진 십진수 문자열이 IEEE 754 4배정밀도 형식으로 변환되어 정규화된 숫자를 생성하고, 동일한 수의 자릿수를 가진 십진수 문자열로 다시 변환되면 최종 결과는 원래 문자열과 일치해야 한다. IEEE 754 4배정밀도 숫자가 최소 36개의 유효 십진수를 가진 십진수 문자열로 변환된 후 다시 4배정밀도 표현으로 변환되면 최종 결과는 원래 숫자와 일치해야 한다.

이 형식은 지수가 모두 0으로 저장되지 않는 한(이는 비정규 값 및 0을 인코딩하는 데 사용됨) 값이 1인 암시적 선행 비트로 작성된다. 따라서 유효숫자의 112비트만 메모리 형식에 나타나지만, 일반 값의 총 정밀도는 113비트(대략 34십진수 자릿수: )이다. 비정규 값은 가장 작은 비영(non-zero) 값의 경우 1비트까지 정밀도가 점진적으로 저하된다. 비트 배치는 다음과 같다.

800px|부호 비트, 15비트 지수, 112비트 유효숫자

### 지수 인코딩
4배정밀도 이진 부동소수점 지수는 오프셋 이진 표현을 사용하여 인코딩되며, 0 오프셋은 16383이다. 이것은 IEEE 754 표준에서 지수 바이어스로도 알려져 있다.

* Emin = 000116 − 3FFF16 = −16382
* Emax = 7FFE16 − 3FFF16 = 16383
* 지수 바이어스 = 3FFF16 = 16383

따라서 오프셋 이진 표현에 의해 정의된 대로 실제 지수를 얻기 위해서는 저장된 지수에서 16383의 오프셋을 빼야 한다.

저장된 지수 000016 및 7FFF16은 특별하게 해석된다.

최소 엄격 양수 (비정규) 값은 2−16494 ≈ 10−4965이며, 정밀도는 단 1비트이다. 최소 양수 정규 값은 2−16382 ≈ 이며, 113비트의 정밀도를 가진다. 즉, ±2−16494와 같다. 최대 표현 가능한 값은  ≈ 이다.

### 4배정밀도 예시
이 예시들은 부동소수점 값의 비트 표현으로, 십육진법으로 주어진다. 여기에는 부호, (바이어스된) 지수, 유효숫자가 포함된다.

 0000 0000 0000 0000 0000 0000 0000 000116 = 2−16382 × 2−112 = 2−16494
                                           ≈ 6.4751751194380251109244389582276465525 × 10−4966
                                             (가장 작은 양수 비정규 값)

 0000 ffff ffff ffff ffff ffff ffff ffff16 = 2−16382 × (1 − 2−112)
                                           ≈ 3.3621031431120935062626778173217519551 × 10−4932
                                             (가장 큰 비정규 값)

 0001 0000 0000 0000 0000 0000 0000 000016 = 2−16382
                                           ≈ 3.3621031431120935062626778173217526026 × 10−4932
                                             (가장 작은 양수 정규 값)

 7ffe ffff ffff ffff ffff ffff ffff ffff16 = 216383 × (2 − 2−112)
                                           ≈ 1.1897314953572317650857593266280070162 × 104932
                                             (가장 큰 정규 값)

 3ffe ffff ffff ffff ffff ffff ffff ffff16 = 1 − 2−113
                                           ≈ 0.9999999999999999999999999999999999037
                                             (1보다 작은 가장 큰 값)

 3fff 0000 0000 0000 0000 0000 0000 000016 = 1 (일)

 3fff 0000 0000 0000 0000 0000 0000 000116 = 1 + 2−112
                                           ≈ 1.0000000000000000000000000000000001926
                                             (1보다 큰 가장 작은 값)

 4000 0000 0000 0000 0000 0000 0000 000016 = 2
 c000 0000 0000 0000 0000 0000 0000 000016 = −2

 0000 0000 0000 0000 0000 0000 0000 000016 = 0
 8000 0000 0000 0000 0000 0000 0000 000016 = −0

 7fff 0000 0000 0000 0000 0000 0000 000016 = 무한대
 ffff 0000 0000 0000 0000 0000 0000 000016 = −무한대

 4000 921f b544 42d1 8469 898c c517 01b816 ≈ 3.1415926535897932384626433832795027975
                                             (π에 가장 가까운 근사치)

 3ffd 5555 5555 5555 5555 5555 5555 555516 ≈ 0.3333333333333333333333333333333333173
                                             (1/3에 가장 가까운 근사치)

기본적으로 1/3은 유효숫자의 비트 수가 홀수이기 때문에 배정밀도처럼 내림한다. 따라서 반올림 지점 너머의 비트는 `0101...`이며, 이는 ULP의 1/2 미만이다.

## 더블-더블 산술
배정밀도 값 쌍을 사용하여 거의 4배정밀도를 구현하는 일반적인 소프트웨어 기술을 때때로 **더블-더블 산술**이라고 한다. 53비트 유효숫자를 가진 IEEE 배정밀도 값 쌍을 사용하면, 더블-더블 산술은 최소  (실제로는 지수 범위가 제한되어 일부 가장 큰 값을 제외하고 107비트)의 유효숫자를 가진 숫자에 대한 연산을 제공하며, IEEE binary128 4배정밀도의 113비트 유효숫자보다 정밀도가 약간 낮다. 더블-더블의 범위는 지수가 여전히 11비트이므로 배정밀도 형식과 본질적으로 동일하게 유지되며, IEEE 4배정밀도의 15비트 지수보다 훨씬 낮다(더블-더블의 범위는 , binary128의 범위는 ).

특히, 더블-더블 기술에서 더블-더블/4배정밀도 값 q는 두 배정밀도 값 x와 y의 합 으로 암시적으로 표현되며, 각 값은 q의 유효숫자 절반을 제공한다. 즉, q 대신 쌍 이 저장되고, q 값에 대한 연산들 은 x와 y 값에 대한 동등한(그러나 더 복잡한) 연산으로 변환된다. 따라서 이 기술의 산술은 일련의 배정밀도 연산으로 축소되며, 배정밀도 산술이 일반적으로 하드웨어에 구현되어 있기 때문에 더블-더블 산술은 일반적으로 더 일반적인 임의 정밀도 산술 기술보다 훨씬 빠르다.

더블-더블 산술은 다음과 같은 특별한 특성을 가진다.

* 값의 크기가 감소함에 따라 추가 정밀도의 양도 감소한다. 따라서 정규화된 범위에서 가장 작은 숫자는 배정밀도보다 범위가 좁다. 완전한 정밀도를 가진 가장 작은 숫자는 , 또는 이다. 크기가 2−1021보다 작은 숫자는 배정밀도에 비해 추가 정밀도를 가지지 않는다.
* 실제 정밀도 비트 수는 달라질 수 있다. 일반적으로 숫자의 하위 부분의 크기는 상위 부분의 ULP의 절반보다 크지 않다. 하위 부분이 상위 부분의 ULP의 절반보다 작으면, 상위 및 하위 숫자의 유효숫자 사이에 유효 비트(모두 0 또는 모두 1)가 암시된다. 유효숫자에 고정된 비트 수를 가지는 것에 의존하는 특정 알고리즘은 128비트 long double 숫자를 사용할 때 실패할 수 있다.
* 위와 같은 이유로, 와 같은 값을 표현할 수 있는데, 이는 1보다 큰 표현 가능한 가장 작은 숫자이다.

더블-더블 산술 외에도, 더 높은 정밀도 부동소수점 라이브러리 없이 더 높은 정밀도가 필요한 경우 트리플-더블 또는 쿼드-더블 산술을 생성하는 것도 가능하다. 이들은 각각 세 개(또는 네 개)의 배정밀도 값의 합으로 표현된다. 이들은 각각 최소 159/161비트 및 212/215비트의 연산을 표현할 수 있다.

유사한 기술을 사용하여 **더블-쿼드 산술**을 생성할 수 있으며, 이는 두 개의 4배정밀도 값의 합으로 표현된다. 이들은 최소 226(또는 227)비트의 연산을 표현할 수 있다.

## 구현
4배정밀도는 종종 다양한 기술(위의 더블-더블 기술과 같은, 비록 그 기술은 IEEE 4배정밀도를 구현하지 않지만)에 의해 소프트웨어로 구현된다. 4배정밀도에 대한 직접적인 하드웨어 지원은  덜 일반적이기 때문이다(아래 "하드웨어 지원" 참조). 일반적인 임의 정밀도 산술 라이브러리를 사용하여 4배정밀도(또는 그 이상)를 얻을 수 있지만, 특수화된 4배정밀도 구현은 더 높은 성능을 달성할 수 있다.

### 컴퓨터 언어 지원
별도의 질문은 4배정밀도 형식이 컴퓨터 프로그래밍 언어에 직접 통합되는 정도이다.

4배정밀도는 포트란에서 `real(real128)` (포트란 2008의 `iso_fortran_env` 모듈을 사용해야 하며, 상수 `real128`은 대부분의 프로세서에서 16과 같다) 또는 `real(selected_real_kind(33, 4931))`로, 또는 비표준 방식으로 `REAL*16`으로 지정된다. (4배정밀도 `REAL*16`은 예를 들어 인텔 포트란 컴파일러 및 GNU 포트란 컴파일러에 의해 X86, X86-64 및 아이테니엄 아키텍처에서 지원된다.)

C 프로그래밍 언어의 경우, ISO/IEC TS 18661-3 (C용 부동소수점 확장, 상호 교환 및 확장형)은 `_Float128`을 IEEE 754 4배정밀도 형식(binary128)을 구현하는 유형으로 지정한다. 또는 일부 시스템과 컴파일러에서 C/C++의 `long double` 유형으로 4배정밀도를 지정할 수 있지만, 이는 언어에 의해 요구되는 사항은 아니며(`long double`은 `double`만큼 정밀해야 한다고만 요구함), 일반적이지도 않다.

x86 및 x86-64에서 가장 일반적인 C/C++ 컴파일러는 `long double`을 80비트 확장 정밀도 (예: GNU C 컴파일러 gcc 및 인텔 C++ 컴파일러의 `/Qlong&#8209;double` 스위치) 또는 단순히 배정밀도와 동의어(예: 마이크로소프트 비주얼 C++)로 구현하며, 4배정밀도로는 구현하지 않는다. ARM 64비트 아키텍처 (AArch64)의 절차 호출 표준은 `long double`이 IEEE 754 4배정밀도 형식에 해당한다고 명시한다. 몇몇 다른 아키텍처에서는 일부 C/C++ 컴파일러가 `long double`을 4배정밀도로 구현한다. 예를 들어 파워PC의 gcc(더블-더블) 및 SPARC, 또는 SPARC의 썬 스튜디오 컴파일러가 그렇다. `long double`이 4배정밀도가 아니더라도, 일부 C/C++ 컴파일러는 확장으로 비표준 4배정밀도 유형을 제공한다. 예를 들어 gcc는 x86, x86-64 및 아이테니엄 CPU용으로 `__float128`이라는 4배정밀도 유형을 제공하며, 파워PC에서는 -mfloat128-hardware 또는 -mfloat128 옵션을 사용하여 IEEE 128비트 부동소수점을 제공한다. 또한 x86 및 x86-64용 인텔 C/C++ 컴파일러의 일부 버전은 `_Quad`라는 비표준 4배정밀도 유형을 제공한다.

Zig는 `f128` 유형으로 이를 지원한다.

구글의 개발 중인 언어 Carbon은 `f128`이라는 유형으로 이를 지원한다.

2024년 현재 러스트는 IEEE 4배정밀도 128비트 부동소수점을 위한 새로운 `f128` 유형을 추가하는 작업을 진행 중이다.

### 라이브러리 및 툴박스
* GCC 쿼드 정밀도 수학 라이브러리인 libquadmath는 `__float128` 및 `__complex128` 연산을 제공한다.
* Boost 다중 정밀도 라이브러리 Boost.Multiprecision은 `__float128` 및 `_Quad` 유형을 위한 통합된 크로스 플랫폼 C++ 인터페이스를 제공하며, 표준 수학 라이브러리의 사용자 지정 구현을 포함한다.
* MATLAB용 다중 정밀도 컴퓨팅 툴박스는 매트랩에서 4배정밀도 계산을 허용한다. 이는 기본 산술 기능뿐만 아니라 수치 방법, 밀집 및 희소 선형 대수를 포함한다.
* DoubleFloats 패키지는 Julia 프로그래밍 언어에서 더블-더블 계산을 지원한다.
* doubledouble.py 라이브러리는 Python에서 더블-더블 계산을 가능하게 한다.

* Mathematica는 IEEE 쿼드 정밀도 숫자: 128비트 부동소수점 값(Real128) 및 256비트 복소수 값(Complex256)을 지원한다.

### 하드웨어 지원
IEEE 4배정밀도는 1998년 IBM 시스템/390 G5에 추가되었고, 이후 z/아키텍처 프로세서에서 하드웨어로 지원된다. IBM POWER9 CPU (Power ISA 3.0)는 네이티브 128비트 하드웨어 지원을 제공한다.

IEEE 128비트 부동소수점의 네이티브 지원은 PA-RISC 1.0, 및 SPARC V8 및 V9 아키텍처(예: 16개의 4배정밀도 레지스터 %q0, %q4 등이 있음)에 정의되어 있지만, 2004년 현재 어떤 SPARC CPU도 하드웨어에서 4배정밀도 연산을 구현하지 않는다.

비-IEEE 확장 정밀도(128비트 저장 공간, 1비트 부호, 7비트 지수, 112비트 분수, 8비트 미사용)는 IBM 시스템/370 시리즈(1970년대–1980년대)에 추가되었으며, 1960년대 일부 System/360 모델(System/360-85, -195 및 기타 특수 요청 또는 OS 소프트웨어로 시뮬레이션)에서 사용 가능했다.

지멘스 7.700 및 7.500 시리즈 메인프레임 및 그 후속 제품은 IBM System/360 및 System/370과 동일한 부동소수점 형식 및 명령어를 지원한다.

VAX 프로세서는 비-IEEE 4배정밀도 부동소수점을 "H 부동소수점" 형식으로 구현했다. 이는 1비트 부호, 15비트 지수, 112비트 분수 부분을 가졌지만, 메모리 레이아웃은 IEEE 4배정밀도와 상당히 달랐고 지수 바이어스도 달랐다. 가장 초기의 VAX 프로세서 중 일부만이 H 부동소수점 명령어를 하드웨어로 구현했고, 다른 모든 프로세서는 소프트웨어로 H 부동소수점을 에뮬레이션했다.

NEC 벡터 엔진 아키텍처는 128비트 이진 IEEE 754 4배정밀도 숫자의 덧셈, 뺄셈, 곱셈, 비교를 지원한다. 인접한 두 64비트 레지스터가 사용된다. 벡터 레지스터에서는 4배정밀도 산술이 지원되지 않는다.

RISC-V 아키텍처는 128비트 이진 IEEE 754-2008 부동소수점 산술을 위한 "Q"(쿼드 정밀도) 확장을 지정한다. "L" 확장(아직 인증되지 않음)은 64비트 및 128비트 십진 부동소수점을 지정한다.

4배정밀도(128비트) 하드웨어 구현은 단일 명령, 다중 데이터 명령(예: 스트리밍 SIMD 확장 또는 AltiVec)을 구현하는 "128비트 FPU"와 혼동해서는 안 된다. 이는 4개의 32비트 단정밀도 또는 2개의 64비트 배정밀도 값으로 구성된 128비트 벡터를 동시에 연산하는 것을 의미한다.

## 같이 보기
* IEEE 754, 부동소수점 산술을 위한 IEEE 표준
* ISO/IEC 10967, 언어 독립 산술
* 원시 자료형
* Q 표기법 (과학적 표기법)

## 각주

## 외부 링크
* 고정밀 소프트웨어 디렉토리
* QPFloat, 4배정밀도 산술을 위한 자유 소프트웨어 (GPL) 소프트웨어 라이브러리
* HPAlib, 4배정밀도 산술을 위한 자유 소프트웨어 (LGPL) 소프트웨어 라이브러리
* libquadmath, GCC 4배정밀도 수학 라이브러리
* IEEE-754 분석, binary32, binary64, binary128 부동소수점 값을 검사하는 대화형 웹 페이지

분류:이진 산술