Fixnums
Fixnums (픽스넘 산술)
머신 정수인 fixnum만 주고받는 안전한 연산들을 제공하는 racket/fixnum 라이브러리를 알아봐요. 산술·비트 연산, fixnum 벡터, fixnum 범위 상수까지 다룹니다.
출처: Racket Reference
본문
4.3.4 Fixnums
(require racket/fixnum)
| package: base |
racket/fixnum 라이브러리는 fx+처럼 fixnums만을 소비하고 생산하는 연산을 제공해요. 이 라이브러리의 연산은 unsafe-fx+ 같은 안전하지 않은 연산의 안전한 버전을 지향합니다. 이런 안전한 연산들은 일반적으로 + 같은 제네릭 기본 연산보다 빠르지 않습니다.
racket/fixnum 라이브러리의 예상 용도는, racket/fixnum의 require를 다음처럼 교체해 라이브러리의 안전하지 않은 버전을 그대로 끼워 넣는 코드예요:
(require (filtered-in
(λ (name)
(and (regexp-match #rx"^unsafe-fx" name)
(regexp-replace #rx"unsafe-" name "")))
racket/unsafe/ops))
( #lang racket/base와 함께 쓰는 방법은 filtered-in 문서를 참고하세요.)
대안으로, 안전하지 않은 fixnum 연산을 쓰는 코드에서 크래시가 날 때 racket/fixnum 라이브러리를 사용해 문제를 디버깅하는 데 도움을 받을 수 있어요.
4.3.4.1 Fixnum 산술
(fx+ a ...) → fixnum? (fx- a b ...) → fixnum? (fx* a ...) → fixnum? (fxquotient a b) → fixnum? (fxremainder a b) → fixnum? (fxmodulo a b) → fixnum? (fxabs a) → fixnum?a : fixnum? b : fixnum?
unsafe-fx+, unsafe-fx-, unsafe-fx*, unsafe-fxquotient, unsafe-fxremainder, unsafe-fxmodulo, unsafe-fxabs의 안전한 버전이에요. 산술 결과가 fixnum이 아니면 exn:fail:contract:non-fixnum-result 예외가 일어납니다.
버전 7.0.0.13의 package base에서 변경됨: fx+와 fx*는 0개 이상의 인자를, fx-는 1개 이상의 인자를 허용.
(fxand a ...) → fixnum? (fxior a ...) → fixnum? (fxxor a ...) → fixnum? (fxnot a) → fixnum? (fxlshift a b) → fixnum? (fxrshift a b) → fixnum?a : fixnum? b : fixnum?
bitwise-and, bitwise-ior, bitwise-xor, bitwise-not, arithmetic-shift와 같지만 fixnums만 소비하도록 제약된 버전이에요. 결과는 항상 fixnum입니다. unsafe-fxlshift와 unsafe-fxrshift 연산은 arithmetic-shift에 대응하지만 음이 아닌 인자를 요구해요. unsafe-fxlshift는 양수(즉, 왼쪽) 시프트이고 unsafe-fxrshift는 음수(즉, 오른쪽) 시프트이며, 시프트할 비트 수는 fixnum을 나타내는 데 쓰이는 비트 수를 넘을 수 없습니다. 산술 결과가 fixnum이 아니면 exn:fail:contract:non-fixnum-result 예외가 일어납니다.
버전 7.0.0.13의 package base에서 변경됨: fxand, fxior, fxxor는 임의 개수의 인자를 허용.
(fxpopcount a) → fixnum? (fxpopcount32 a) → fixnum? (fxpopcount16 a) → fixnum?a : (and/c fixnum? (not/c negative?)) ; fxpopcount a : (and/c fixnum? (integer-in 0 #xFFFFFFFF)) ; fxpopcount32 a : (and/c fixnum? (integer-in 0 #xFFFF)) ; fxpopcount16
a의 2의 보수 표현에서 1로 설정된 비트의 개수를 셉니다. 플랫폼에 따라, 결과가 각각 32 또는 16 이하임이 알려져 있으면 fxpopcount32와 fxpopcount16 연산이 더 빠를 수 있어요.
버전 8.5.0.7의 package base에서 추가됨.
(fx+/wraparound a b) → fixnum? (fx-/wraparound [a] b) → fixnum? (fx*/wraparound a b) → fixnum? (fxlshift/wraparound a b) → fixnum?a : fixnum? = 0 (fx-/wraparound) b : fixnum?
fx+, fx-, fx*, fxlshift와 같지만, 허용된 인자에 대해 항상 fixnum 결과를 만듭니다(즉, 어떤 fixnum 인자에 대해서도, 단 두 번째 fxlshift/wraparound 인자는 0과 fixnum의 비트 수 사이(포함)여야 함). 결과는 fixnum 표현에 맞지 않는 비트를 그냥 버려서 만들어집니다. 유지된 비트 중 최상위 비트가 설정되어 있으면 결과는 음수예요. 예를 들어 두 양의 fixnum을 더해서 만들어진 값이라도 그럴 수 있습니다.
버전 7.9.0.6의 package base에서 추가됨.
버전 8.15.0.12에서 변경됨: fx-/wraparound이 단일 인자를 받도록 변경.
(fxrshift/logical a b) → fixnum?a : fixnum? b : fixnum?
a의 비트를 오른쪽으로 b만큼 시프트하고, 빈 자리를 0으로 채웁니다. 부호 비트를 그냥 또 하나의 비트로 취급하면, 음수로 부호가 붙은 fixnum의 논리 오른쪽 시프트는 큰 양의 fixnum을 만들 수 있어요. 예를 들어 (fxrshift/logical -1 1)은 (most-positive-fixnum)을 만드는데, 이는 논리 오른쪽 시프트 결과가 플랫폼에 따라 다름을 보여줘요.
예시:
(fxrshift/logical 128 2)
; 32
(fxrshift/logical 255 4)
; 15
(= (fxrshift/logical -1 1) (most-positive-fixnum))
; #t
버전 8.8.0.5의 package base에서 추가됨.
(fx= a b ...) → boolean? (fx< a b ...) → boolean? (fx> a b ...) → boolean? (fx<= a b ...) → boolean? (fx>= a b ...) → boolean? (fxmin a b ...) → fixnum? (fxmax a b ...) → fixnum?a : fixnum? b : fixnum?
=, <, >, <=, >=, min, max와 같지만 fixnums만 소비하도록 제약된 버전이에요.
버전 7.0.0.13의 package base에서 변경됨: 두 개 이상에 더해 한 개의 인자도 허용.
(fx->fl a) → flonum? (fl->fx fl) → fixnum?a : fixnum? fl : flonum?
fixnums와 flonums 사이의 변환이에요. flonum을 fixnum으로 변환할 때는 절삭(truncate)합니다.
fx->fl 함수는 exact->inexact 또는 ->fl을 fixnum 인자로 제약한 것과 같아요.
fl->fx 함수는 truncate 다음에 inexact->exact 또는 fl->exact-integer을 수행하고 fixnum을 반환하도록 제약한 것과 같아요. 절삭된 flonum이 fixnum에 맞지 않으면 exn:fail:contract 예외가 일어납니다.
버전 7.7.0.8의 package base에서 변경됨: fl->fx를 절삭(truncate)으로 변경.
(fixnum-for-every-system? v) → boolean?v : any/c
v가 fixnum이고 모든 Racket 구현에서 fixnum으로 표현된다면 #t를, 그렇지 않으면 #f를 반환합니다.
버전 7.3.0.11의 package base에서 추가됨.
4.3.4.2 Fixnum 벡터
fxvector는 vector와 같지만 fixnums만 담아요. fxvector가 vector보다 나은 유일한 장점은 shared-fxvector 같은 함수로 공유 버전을 만들 수 있다는 거예요.
두 fxvector는 길이가 같고 대응하는 슬롯의 값들이 equal?하면 equal?합니다.
출력된 fxvector는 #fx(로 시작하고, 선택적으로 #fx와 ( 사이에 숫자가 들어갈 수 있어요. fxvector를 read하는 방법은 Reading Vectors, print하는 방법은 Printing Vectors을 참고하세요.
(fxvector? v) → boolean?v : any/c
v가 fxvector이면 #t를, 그렇지 않으면 #f를 반환합니다.
(fxvector x ...) → fxvector?x : fixnum?
주어진 fixnums를 담은 fxvector를 만듭니다.
예시:
(fxvector 2 3 4 5)
; (fxvector 2 3 4 5)
(make-fxvector size [x]) → fxvector?size : exact-nonnegative-integer? x : fixnum? = 0
size개의 요소를 가진 fxvector를 만들고, 각 슬롯을 x로 채웁니다.
예시:
(make-fxvector 4 3)
; (fxvector 3 3 3 3)
(fxvector-length vec) → exact-nonnegative-integer?vec : fxvector?
vec의 길이(즉 fxvector의 슬롯 수)를 반환합니다.
(fxvector-ref vec pos) → fixnum?vec : fxvector? pos : exact-nonnegative-integer?
vec의 pos 슬롯에 있는 fixnum을 반환합니다. 첫 번째 슬롯은 위치 0이고, 마지막 슬롯은 (fxvector-length vec)보다 하나 작습니다.
(fxvector-set! vec pos x) → fixnum?vec : fxvector? pos : exact-nonnegative-integer? x : fixnum?
vec의 pos 슬롯에 있는 fixnum을 설정합니다. 첫 번째 슬롯은 위치 0이고, 마지막 슬롯은 (fxvector-length vec)보다 하나 작습니다.
(fxvector-copy vec [start end]) → fxvector?vec : fxvector? start : exact-nonnegative-integer? = 0 end : exact-nonnegative-integer? = (vector-length v)
크기 (- end start)의 새 fxvector를 만들고, vec의 start(포함)부터 end(제외)까지의 모든 요소를 담습니다.
(in-fxvector vec [start stop step]) → sequence?vec : fxvector? 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-fxvector 적용이 for 절에 직접 나타나면 fxvector 순회에 더 나은 성능을 제공할 수 있어요.
(for/fxvector maybe-length (for-clause ...) body ...) (for*/fxvector maybe-length (for-clause ...) body ...)maybe-length | = | #:length length-expr | | #:length length-expr #:fill fill-expr length-expr : exact-nonnegative-integer? fill-expr : fixnum?
for/vector나 for*/vector와 같지만 fxvector용이에요. 기본 fill-expr은 0을 만듭니다.
(shared-fxvector x ...) → fxvector?x : fixnum?
주어진 fixnums를 담은 fxvector를 만듭니다. places 사이의 통신을 위해, 새 fxvector는 shared memory space에 할당됩니다.
예시:
(shared-fxvector 2 3 4 5)
; (fxvector 2 3 4 5)
(make-shared-fxvector size [x]) → fxvector?size : exact-nonnegative-integer? x : fixnum? = 0
size개의 요소를 가진 fxvector를 만들고, 각 슬롯을 x로 채웁니다. places 사이의 통신을 위해, 새 fxvector는 shared memory space에 할당됩니다.
예시:
(make-shared-fxvector 4 3)
; (fxvector 3 3 3 3)
4.3.4.3 Fixnum 범위
(most-positive-fixnum) → fixnum? (most-negative-fixnum) → fixnum?
크기가 가장 큰 양수와 음수 fixnums를 반환합니다. (most-positive-fixnum)과 (most-negative-fixnum)의 값은 플랫폼과 가상 머신에 따라 달라지지만, 모든 fixnum은 (most-negative-fixnum)부터 (most-positive-fixnum)까지(포함) 범위에 있고, 그 범위의 모든 정확한 정수는 fixnum입니다.
버전 8.1.0.7의 package base에서 추가됨.