Flonums

Flonums (플로넘 산술)

racket/flonum 라이브러리가 제공하는, flonum(배정밀도 부동소수점)만 주고받는 안전한 연산들을 알아봐요. 산술·비교·삼각함수, flonum 벡터까지 다룹니다.

출처: Racket Reference

본문

4.3.3 Flonums

(require racket/flonum)
package: base

racket/flonum 라이브러리는 fl+처럼 flonums만을 소비하고 생산하는 연산을 제공해요. flonum 전용 연산은 일관되게 사용하면 더 나은 성능을 낼 수 있고, + 같은 제네릭 연산만큼 안전합니다.

(The Racket GuideFixnum and Flonum Optimizations도 참고하세요.)

4.3.3.1 Flonum 산술

(fl+ a ...) → flonum?          (fl- a b ...) → flonum?
(fl* a ...) → flonum?          (fl/ a b ...) → flonum?
(flabs a) → flonum?
a : flonum?
b : flonum?

+, -, *, /, abs와 같지만 flonums만 소비하도록 제약된 버전이에요. 결과는 항상 flonum입니다.

버전 7.0.0.13의 package base에서 변경됨: fl+fl*는 0개 이상의 인자를, fl-fl/는 1개 이상의 인자를 허용.

(fl= a b ...) → boolean?       (fl< a b ...) → boolean?
(fl> a b ...) → boolean?       (fl<= a b ...) → boolean?
(fl>= a b ...) → boolean?      (flmin a b ...) → flonum?
(flmax a b ...) → flonum?
a : flonum?
b : flonum?

=, <, >, <=, >=, min, max와 같지만 flonums만 소비하도록 제약된 버전이에요.

버전 7.0.0.13의 package base에서 변경됨: 두 개 이상에 더해 한 개의 인자도 허용.

(flround a) → flonum?          (flfloor a) → flonum?
(flceiling a) → flonum?        (fltruncate a) → flonum?
a : flonum?

round, floor, ceiling, truncate와 같지만 flonums만 소비하도록 제약된 버전이에요.

(flsingle a) → flonum?
a : flonum?

a와 같은 값을 반환하지만, 결과가 단정밀도 IEEE 부동소수점 숫자로 표현될 수 있도록 정밀도와 범위를 잠재적으로 버릴 수 있어요(single-flonums이 지원되지 않더라도).

fl+, fl-, fl*, fl/, flsqrt의 인자와 결과에 flsingle을 사용하는 것, 즉 단정밀도로 표현 가능한 값에 배정밀도 연산을 수행한 뒤 결과를 단정밀도로 반올림하는 것은 항상 대응하는 단정밀도 연산을 수행하는 것과 같아요 [Roux14]. (다른 연산에 대해서는 IEEE 부동소수점 명세가 flsingle과의 상호작용에 대해 더 말할 만큼 충분한 보장을 하지 않습니다.)

버전 7.8.0.7의 package base에서 추가됨.

(flbit-field a start end) → exact-nonnegative-integer?
a     : flonum?
start : (integer-in 0 64)
end   : (integer-in 0 64)

a의 64비트 IEEE 표현에서 비트 범위를 추출해, 그 (반무한) 2의 보수 표현에서 같은 비트가 설정된 음이 아닌 정수를 반환합니다.

예시:

(flbit-field -0.0 63 64)
; 1
(format "~x" (flbit-field 3.141579e+132 16 48))
; "b43544f2"

버전 8.15.0.3의 package base에서 추가됨.

(flsin a) → flonum?            (flcos a) → flonum?
(fltan a) → flonum?            (flasin a) → flonum?
(flacos a) → flonum?           (flatan a) → flonum?
(fllog a) → flonum?            (flexp a) → flonum?
(flsqrt a) → flonum?
a : flonum?

sin, cos, tan, asin, acos, atan, log, exp, sqrt와 같지만 flonums만 소비하고 생산하도록 제약된 버전이에요. flasin이나 flacos에 -1.0에서 1.0 범위 밖의 숫자가 주어지거나, fllogflsqrt에 음수가 주어지면 결과는 +nan.0입니다.

(flexpt a b) → flonum?
a : flonum?
b : flonum?

expt와 같지만 flonums만 소비하고 생산하도록 제약된 버전이에요.

결과 제약 때문에 expt와 비교한 결과는 다음 경우에 달라져요. 이 특수 경우들은 C99 [C99]의 pow에 해당합니다.

  • (flexpt -1.0 +inf.0) — 1.0

  • (flexpt a +inf.0), a가 음수일 때 — (expt (abs a) +inf.0)

  • (flexpt a -inf.0), a가 음수일 때 — (expt (abs a) -inf.0)

  • (expt -inf.0 b), b가 정수가 아닐 때:

    • b가 음수 — 0.0

    • b가 양수 — +inf.0

  • (flexpt a b), a가 음수이고 b가 정수가 아닐 때 — +nan.0

(->fl a) → flonum?
a : exact-integer?

exact->inexact와 같지만 정확한 정수만 소비하도록 제약되어, 결과는 항상 flonum입니다.

(fl->exact-integer a) → exact-integer?
a : flonum?

inexact->exact와 같지만 integer flonum만 소비하도록 제약되어, 결과는 항상 정확한 정수입니다.

(make-flrectangular a b) → (and/c complex?
                               (lambda (c) (flonum? (real-part c)))
                               (lambda (c) (flonum? (imag-part c))))
a : flonum?
b : flonum?
(flreal-part a) → flonum?
(flimag-part a) → flonum?
a : (and/c complex?
       (lambda (c) (flonum? (real-part c)))
       (lambda (c) (flonum? (imag-part c))))

make-rectangular, real-part, imag-part와 같지만, 복소수의 두 부분이 모두 inexact여야 해요.

(flrandom rand-gen) → (and flonum? (>/c 0) (</c 1))
rand-gen : pseudo-random-generator?

(random rand-gen)과 동등합니다.

4.3.3.2 Flonum 벡터

flvector는 vector와 같지만 inexact 실수만 담아요. 이 표현은 더 컴팩트할 수 있고, flvector에 대한 안전하지 않은 연산(〔racket/unsafe/ops〕 참고)은 inexact 실수의 vectors에 대한 안전하지 않은 연산보다 더 효율적으로 실행될 수 있어요.

ffi/vector가 제공하는 f64vector는 flvector와 같은 종류의 값을 저장하지만, f64vector를 외부 라이브러리 작업에 더 편리하게 만들기 위한 추가 간접(indirection)을 가져요. 간접이 없다는 점이 안전하지 않은 flvector 접근을 더 효율적으로 만들어요.

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

출력된 flvector는 #fl(로 시작하고, 선택적으로 #fl( 사이에 숫자가 들어갈 수 있어요. flvector를 read하는 방법은 Reading Vectors, print하는 방법은 Printing Vectors을 참고하세요.

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

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

(flvector x ...) → flvector?
x : flonum?

주어진 inexact 실수를 담은 flvector를 만듭니다.

예시:

(flvector 2.0 3.0 4.0 5.0)
; (flvector 2.0 3.0 4.0 5.0)
(make-flvector size [x]) → flvector?
size : exact-nonnegative-integer?
x    : flonum? = 0.0

size개의 요소를 가진 flvector를 만들고, 각 슬롯을 x로 채웁니다.

예시:

(make-flvector 4 3.0)
; (flvector 3.0 3.0 3.0 3.0)
(flvector-length vec) → exact-nonnegative-integer?
vec : flvector?

vec의 길이(즉 flvector의 슬롯 수)를 반환합니다.

(flvector-ref vec pos) → flonum?
vec : flvector?
pos : exact-nonnegative-integer?

vecpos 슬롯에 있는 inexact 실수를 반환합니다. 첫 번째 슬롯은 위치 0이고, 마지막 슬롯은 (flvector-length vec)보다 하나 작습니다.

(flvector-set! vec pos x) → flonum?
vec : flvector?
pos : exact-nonnegative-integer?
x   : flonum?

vecpos 슬롯에 있는 inexact 실수를 설정합니다. 첫 번째 슬롯은 위치 0이고, 마지막 슬롯은 (flvector-length vec)보다 하나 작습니다.

(flvector-copy vec [start end]) → flvector?
vec   : flvector?
start : exact-nonnegative-integer? = 0
end   : exact-nonnegative-integer? = (vector-length v)

크기 (- end start)의 새 flvector를 만들고, vecstart(포함)부터 end(제외)까지의 모든 요소를 담습니다.

(in-flvector vec [start stop step]) → sequence?
vec   : flvector?
start : exact-nonnegative-integer? = 0
stop  : (or/c exact-integer? #f) = #f
step  : (and/c exact-integer? (not/c zero?)) = 1

선택 인자가 주어지지 않으면 vec과 동등한 시퀀스를 반환합니다.

선택 인자 start, stop, stepin-vector와 같아요.

in-flvector 적용이 for 절에 직접 나타나면 flvector 순회에 더 나은 성능을 제공할 수 있어요.

(for/flvector maybe-length (for-clause ...) body ...)
(for*/flvector maybe-length (for-clause ...) body ...)
maybe-length | = | #:length length-expr
             |   | #:length length-expr #:fill fill-expr
length-expr : exact-nonnegative-integer?
fill-expr   : flonum?

for/vectorfor*/vector와 같지만 flvector용이에요. 기본 fill-expr은 0.0을 만듭니다.

(shared-flvector x ...) → flvector?
x : flonum?

주어진 inexact 실수를 담은 flvector를 만듭니다. places 사이의 통신을 위해, 새 flvector는 shared memory space에 할당됩니다.

예시:

(shared-flvector 2.0 3.0 4.0 5.0)
; (flvector 2.0 3.0 4.0 5.0)
(make-shared-flvector size [x]) → flvector?
size : exact-nonnegative-integer?
x    : flonum? = 0.0

size개의 요소를 가진 flvector를 만들고, 각 슬롯을 x로 채웁니다. places 사이의 통신을 위해, 새 flvector는 shared memory space에 할당됩니다.

예시:

(make-shared-flvector 4 3.0)
; (flvector 3.0 3.0 3.0 3.0)

더 알아보기