Extflonums

Extflonums (확장 정밀 부동소수점)

기존 flonum보다 정밀도가 높은 확장 정밀도(80비트) 부동소수점 숫자인 extflonum에 대해 알아봐요. 산술 연산과 변환, 벡터, 바이트 문자열 변환 함수들을 다룹니다.

출처: Racket Reference

본문

4.3.5 Extflonums

(require racket/extflonum)
package: base

extflonum은 확장 정밀도(80비트) 부동소수점 숫자예요. extflonum 산술은 확장 정밀도 하드웨어가 있고 extflonum 구현이 일반적인 배정밀도 산술과 충돌하지 않는 플랫폼에서 지원됩니다 (즉, Racket이 부동소수점 연산에 SSE 명령을 사용하도록 컴파일된 x86과 x86_64 플랫폼, 그리고 "longdouble.dll"을 사용할 수 있는 Windows에서).

extflonum은 number?의 의미에서 number가 아니에요. extfl+ 같은 extflonum 전용 연산만이 extflonum 산술을 수행합니다.

리터럴 extflonum은 inexact number처럼 쓰지만, 명시적인 t 또는 T 지수 표기를 사용해요 (〔Reading Extflonums〕 참고). 예를 들어 3.5t0은 extflonum입니다. 무한대의 extflonum 값은 +inf.t-inf.t예요. 숫자가 아님(not-a-number)의 extflonum 값은 +nan.t 또는 -nan.t입니다.

(extflonum-available?)#f를 만들면, racket/extflonum이 내보내는 모든 연산이 exn:fail:unsupported를 일으켜요. 단, extflonum?, extflonum-available?, extflvector?는 항상 동작합니다. 리더(〔The Reader〕 참고)는 항상 extflonum 입력을 받아들이는데, extflonum 연산이 지원되지 않으면 리더에서 extflonum을 출력할 때 형식을 정규화하지 않고 원본 표기를 사용합니다.

두 extflonum은 flonums와 같은 방식으로 equal?합니다: extfl=이면서 부호가 같을 때(-0.0t0+0.0t0에서 중요) 또는 둘 다 +nan.t일 때 그렇죠. 플랫폼에서 extflonum이 지원되지 않으면 extflonum은 eq?일 때만 equal?합니다.

(extflonum? v) → boolean?
v : any/c

v가 extflonum이면 #t를, 그렇지 않으면 #f를 반환합니다.

(extflonum-available?) → boolean?

현재 플랫폼에서 extflonum 연산이 지원되면 #t를, 그렇지 않으면 #f를 반환합니다.

4.3.5.1 Extflonum 산술

(extfl+ a b) → extflonum?     (extfl- a b) → extflonum?
(extfl* a b) → extflonum?     (extfl/ a b) → extflonum?
(extflabs a) → extflonum?
a : extflonum?
b : extflonum?

fl+, fl-, fl*, fl/, flabs와 같지만 extflonum용이에요.

(extfl= a b) → boolean?       (extfl< a b) → boolean?
(extfl> a b) → boolean?       (extfl<= a b) → boolean?
(extfl>= a b) → boolean?      (extflmin a b) → extflonum?
(extflmax a b) → extflonum?
a : extflonum?
b : extflonum?

fl=, fl<, fl>, fl<=, fl>=, flmin, flmax와 같지만 extflonum용이에요.

(extflround a) → extflonum?    (extflfloor a) → extflonum?
(extflceiling a) → extflonum?  (extfltruncate a) → extflonum?
a : extflonum?

flround, flfloor, flceiling, fltruncate와 같지만 extflonum용이에요.

(extflsin a) → extflonum?      (extflcos a) → extflonum?
(extfltan a) → extflonum?      (extflasin a) → extflonum?
(extflacos a) → extflonum?     (extflatan a) → extflonum?
(extfllog a) → extflonum?      (extflexp a) → extflonum?
(extflsqrt a) → extflonum?     (extflexpt a b) → extflonum?
a : extflonum?
b : extflonum?

flsin, flcos, fltan, flasin, flacos, flatan, fllog, flexp, flsqrt, flexpt와 같지만 extflonum용이에요.

(->extfl a) → extflonum?              (extfl->exact-integer a) → exact-integer?
(real->extfl a) → extflonum?          (extfl->exact a) → (and/c real? exact?)
(extfl->fx a) → fixnum?               (fx->extfl a) → fixnum?
(extfl->inexact a) → flonum?
a : exact-integer? (->extfl의 경우)
a : extflonum?     (그 외)

처음 여섯 개는 ->fl, fl->exact-integer, real->double-flonum, inexact->exact, fl->fx, fx->fl와 같지만 extflonum용이에요. extfl->inexact 함수는 extflonum을 가장 가까운 flonum 근삿값으로 변환합니다.

버전 7.7.0.8의 package base에서 변경됨: extfl->fx를 절삭(truncate)으로 변경.

4.3.5.2 Extflonum 상수

pi.t : extflonum?

pi와 같지만 80비트 정밀도를 가져요.

4.3.5.3 Extflonum 벡터

extflvector는 flvector와 같지만 extflonum만 담아요. Unsafe Extflonum Operations도 참고하세요.

두 extflvector는 길이가 같고, 대응하는 슬롯의 값들이 equal?하면 equal?합니다.

(extflvector? v) → boolean?               (extflvector x ...) → extflvector?
(make-extflvector size [x]) → extflvector?  (extflvector-length vec) → exact-nonnegative-integer?
(extflvector-ref vec pos) → extflonum?     (extflvector-set! vec pos x) → extflonum?
(extflvector-copy vec [start end]) → extflvector?
v    : any/c
x    : extflonum?
size : exact-nonnegative-integer?
x    : extflonum? = 0.0t0 (make-extflvector)
vec  : extflvector?
pos  : exact-nonnegative-integer?
start : exact-nonnegative-integer? = 0
end   : exact-nonnegative-integer? = (vector-length v)

flvector?, flvector, make-flvector, flvector-length, flvector-ref, flvector-set, flvector-copy와 같지만 extflvector용이에요.

(in-extflvector vec [start stop step]) → sequence?
vec   : extflvector?
start : exact-nonnegative-integer? = 0
stop  : (or/c exact-integer? #f) = #f
step  : (and/c exact-integer? (not/c zero?)) = 1
(for/extflvector maybe-length (for-clause ...) body ...)
(for*/extflvector maybe-length (for-clause ...) body ...)
maybe-length | = | #:length length-expr
             |   | #:length length-expr #:fill fill-expr
length-expr : exact-nonnegative-integer?
fill-expr   : extflonum?

in-flvector, for/flvector, for*/flvector와 같지만 extflvector용이에요.

(shared-extflvector x ...) → extflvector?
(make-shared-extflvector size [x]) → extflvector?
x    : extflonum?
size : exact-nonnegative-integer?
x    : extflonum? = 0.0t0

shared-flvectormake-shared-flvector와 같지만 extflvector용이에요.

4.3.5.4 Extflonum 바이트 문자열

(floating-point-bytes->extfl bstr [big-endian? start end]) → extflonum?
bstr        : bytes?
big-endian? : any/c = (system-big-endian?)
start       : exact-nonnegative-integer? = 0
end         : exact-nonnegative-integer? = (bytes-length bstr)

floating-point-bytes->real와 같지만 extflonum용이에요: bstr에 인코딩된 확장 정밀도 부동소수점 숫자를 start 위치(포함)에서 end 위치(제외)까지 변환해 extflonum으로 만듭니다. startend의 차이는 10바이트여야 해요.

(extfl->floating-point-bytes x [big-endian? dest-bstr start]) → bytes?
x           : extflonum?
big-endian? : any/c = (system-big-endian?)
dest-bstr   : (and/c bytes? (not/c immutable?)) = (make-bytes 10)
start       : exact-nonnegative-integer? = 0

real->floating-point-bytes와 같지만 extflonum용이에요: x를 길이 10의 바이트 문자열 표현으로 변환합니다.

더 알아보기