Flonums
Flonums (플로넘 산술)
racket/flonum 라이브러리가 제공하는, flonum(배정밀도 부동소수점)만 주고받는 안전한 연산들을 알아봐요. 산술·비교·삼각함수, flonum 벡터까지 다룹니다.
출처: Racket Reference
본문
4.3.3 Flonums
(require racket/flonum)
| package: base |
racket/flonum 라이브러리는 fl+처럼 flonums만을 소비하고 생산하는 연산을 제공해요. flonum 전용 연산은 일관되게 사용하면 더 나은 성능을 낼 수 있고, + 같은 제네릭 연산만큼 안전합니다.
(The Racket Guide의 Fixnum 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 범위 밖의 숫자가 주어지거나, fllog나 flsqrt에 음수가 주어지면 결과는 +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?
vec의 pos 슬롯에 있는 inexact 실수를 반환합니다. 첫 번째 슬롯은 위치 0이고, 마지막 슬롯은 (flvector-length vec)보다 하나 작습니다.
(flvector-set! vec pos x) → flonum?vec : flvector? pos : exact-nonnegative-integer? x : flonum?
vec의 pos 슬롯에 있는 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를 만들고, vec의 start(포함)부터 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, step은 in-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/vector나 for*/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)