R6RS Scheme: 산술
R6RS Scheme: 산술
기본 라이브러리가 제공하는 산술 연산을 설명해요. 3장에서 설명한 수치 탑(numerical tower) 위에서 동작하는 일반적(generic)인 수치 연산 프로시저들을 프로시저별 시그니처와 의미, 예시까지 빠짐없이 다뤄요.
출처: 문서
본문
여기서 설명하는 프로시저들은 3장에서 설명한 수치 탑 위에서 일반적인(generic) 산술을 구현해요. 이 절에서 설명하는 일반 프로시저들은 정확한(exact) 수치 객체와 부정확한(inexact) 수치 객체를 모두 인자로 받아들이고, 인자들의 수치 하위 타입에 따라 강제 변환(coercion)을 수행하고 적절한 연산을 선택해요.
"산술"에 대한 라이브러리 장은 다른 수치 프로시저들을 정의하는 라이브러리들을 설명해요.
정확성과 부정확성의 전파 (11.7.1절)
아래에 나열된 프로시저들은 모든 인자가 정확하면 수학적으로 정확한 결과를 반환해야 해요:
+ - *
max min abs
numerator denominator gcd
lcm floor ceiling
truncate round rationalize
real-part imag-part make-rectangular
아래에 나열된 프로시저들은 모든 인자가 정확하고 나누는 수(divisor)가 어떤 것도 0이 아니면 정확한 결과를 반환해야 해요:
/
div mod div-and-mod
div0 mod0 div0-and-mod0
게다가 expt 프로시저는 첫 번째 인자가 정확한 실수 수치 객체이고 두 번째 인자가 정확한 정수 수치 객체이면 정확한 결과를 반환해야 해요.
일반 규칙은, 일반 연산들이 모든 인자가 정확하고 결과가 수학적으로 잘 정의되는 경우 정확한 결과를 반환하지만, 어떤 인자가 부정확하면 부정확한 결과를 반환한다는 것이에요. 이 규칙의 예외에는 sqrt, exp, log, sin, cos, tan, asin, acos, atan, expt, make-polar, magnitude, angle가 있는데, 이들은 이 프로시저들의 명세에서 표시된 대로 정확한 인자가 주어져도 부정확한 결과를 반환할 수 있어요(그렇게 할 것이 요구되지는 않아요).
위 규칙에 대한 일반적인 예외 하나는, 구현이 부정확한 인자에도 불구하고 그 정확한 결과가 부정확한 인자들에 대한 정확한 인자로 대체할 수 있는 모든 경우에 대한 올바른 결과가 될 것이라면 정확한 결과를 반환할 수 있다는 것이에요. 예를 들어 (* 1.0 0)은 0(정확) 또는 0.0(부정확)을 반환할 수 있어요.
무한대와 NaN의 표현 가능성 (11.7.2절)
수치 연산의 명세는 무한대와 NaN이 표현 가능한 것처럼 쓰여 있고, 이 수치 객체들에 대해 많은 연산을 2진 부동소수점 산술에 대한 IEEE-754 표준과 일치하는 방식으로 명시해요. Scheme 구현은 무한대와 NaN을 표현할 수도 있고 하지 않을 수도 있어요; 그러나 구현은 명시된 대로 무한대나 NaN을 표현할 수 없을 때마다 조건 타입 &no-infinities 또는 &no-nans(각각; "Flonums" 라이브러리 절 참조)을 가진 계속 가능한 예외(continuable exception)를 일으켜야 해요. 이 경우 예외 처리기의 연속체는 그렇지 않았다면 무한대 또는 NaN 값을 받았을 연속체예요. 이 요구 사항은 수치 객체와 외부 표현 사이의 변환에도 적용되는데, 프로그램 소스 코드를 읽는 것도 포함해요.
공통 연산의 의미 (11.7.3절)
일부 연산은 여러 산술 프로시저의 의미론적 기반이 돼요. 이 연산들의 동작은 나중에 참조하기 위해 이 절에서 설명해요.
정수 나눗셈 (11.7.3.1절)
정수 나눗셈을 수행하는 Scheme의 연산들은 수학적 연산 div, mod, div0, mod0에 의존하는데, 이것들은 다음과 같이 정의돼요.
div, mod, div0, mod0은 각각 두 실수 x1과 x2를 피연산자로 받아들이는데, x2는 0이 아니어야 해요.
div는 정수를 반환하고 mod는 실수를 반환해요. 그 결과들은 다음으로 명시돼요.
x1 div x2 = nd
x1 mod x2 = xm
여기서
x1 = nd·x2 + xm
0 ≤ xm < |x2|
예:
123 div 10 = 12
123 mod 10 = 3
123 div −10 = −12
123 mod −10 = 3
−123 div 10 = −13
−123 mod 10 = 7
−123 div −10 = 13
−123 mod −10 = 7
div0와 mod0은 div와 mod와 같되, mod0의 결과가 0을 중심으로 한 반 개방 구간(half-open interval) 안에 있는다는 점이 달라요. 그 결과들은 다음으로 명시돼요:
x1 div0 x2 = nd
x1 mod0 x2 = xm
여기서
x1 = nd·x2 + xm
−|x2|/2 ≤ xm < |x2|/2
예:
123 div0 10 = 12
123 mod0 10 = 3
123 div0 −10 = −12
123 mod0 −10 = 3
−123 div0 10 = −12
−123 mod0 10 = −3
−123 div0 −10 = 12
−123 mod0 −10 = −3
초월 함수 (11.7.3.2절)
일반적으로 초월 함수 log, sin⁻¹(아크사인), cos⁻¹(아크코사인), tan⁻¹은 다가(multiply defined) 함수예요. log z의 값은 그 허수부가 −π(에서 −0.0이 구별되는 경우에는 포함, 그렇지 않으면 배제)부터 π(포함)까지의 범위에 있는 것으로 정의돼요. log 0은 미정의예요.
비-실수 z에 대한 log z의 값은 실수에 대한 log로 다음과 같이 정의돼요:
log z = log |z| + (angle z) i
여기서 z = a·e^(i·b)의 각 angle z는 다음과 같이 명시돼요:
angle z = b + 2nπ
−π ≤ angle z ≤ π이고 어떤 정수 n에 대해 angle z = b + 2nπ일 때.
단일-인자 버전의 log를 이렇게 정의하면, 두-인자 버전의 log, sin⁻¹ z, cos⁻¹ z, tan⁻¹ z 및 두-인자 버전의 tan⁻¹의 값은 다음 공식에 따르게 돼요:
log z b = (log z / log b)
sin⁻¹ z = −i log (i z + (1 − z²)^(1/2))
cos⁻¹ z = π/2 − sin⁻¹ z
tan⁻¹ z = (log (1 + i z) − log (1 − i z)) / (2 i)
tan⁻¹ x y = angle(x + y i)
tan⁻¹ x y의 범위는 다음 표와 같아요. 별표(*)는 마이너스 0을 구별하는 구현에 항목이 적용됨을 나타내요.
y 조건 x 조건 결과 r의 범위
y = 0.0 x > 0.0 0.0
∗ y = +0.0 x > 0.0 +0.0
∗ y = −0.0 x > 0.0 −0.0
y > 0.0 x > 0.0 0.0 < r < (π/2)
y > 0.0 x = 0.0 (π/2)
y > 0.0 x < 0.0 (π/2) < r < π
y = 0.0 x < 0 π
∗ y = +0.0 x < 0.0 π
∗ y = −0.0 x < 0.0 −π
y < 0.0 x < 0.0 −π < r < −(π/2)
y < 0.0 x = 0.0 −(π/2)
y < 0.0 x > 0.0 −(π/2) < r < 0.0
y = 0.0 x = 0.0 undefined
∗ y = +0.0 x = +0.0 +0.0
∗ y = −0.0 x = +0.0 −0.0
∗ y = +0.0 x = −0.0 π
∗ y = −0.0 x = −0.0 −π
∗ y = +0.0 x = 0 (π/2)
∗ y = −0.0 x = 0 −(π/2)
수치 연산 (11.7.4절)
수치 타입 술어 (11.7.4.1절)
(number? obj) — procedure
(complex? obj) — procedure
(real? obj) — procedure
(rational? obj) — procedure
(integer? obj) — procedure
이 수치 타입 술어들은 어떤 종류의 인자에도 적용될 수 있어요. 객체가 명명된 타입의 수치 객체이면 #t를, 그렇지 않으면 #f를 반환해요. 일반적으로 어떤 타입 술어가 수치 객체에 대해 참이면 모든 더 높은 타입 술어들도 그 수치 객체에 대해 참이에요. 따라서 어떤 타입 술어가 수치 객체에 대해 거짓이면 모든 더 낮은 타입 술어들도 그 수치 객체에 대해 거짓이에요.
z가 복소수 수치 객체이면, (real? z)는 (zero? (imag-part z))와 (exact? (imag-part z))가 둘 다 참일 때 그리고 오직 그때 참이에요.
x가 실수 수치 객체이면, (rational? x)는 정확한 정수 수치 객체 k1과 k2가 존재해서 (= x (/ k1 k2)), (= (numerator x) k1), (= (denominator x) k2)가 모두 참일 때 그리고 오직 그때 참이에요. 따라서 무한대와 NaN은 유리수 수치 객체가 아니에요.
q가 유리수 수치 객체이면, (integer? q)는 (= (denominator q) 1)이 참일 때 그리고 오직 그때 참이에요. q가 유리수 수치 객체가 아니면 (integer? q)는 #f예요.
(complex? 3+4i) ⇒ #t
(complex? 3) ⇒ #t
(real? 3) ⇒ #t
(real? -2.5+0.0i) ⇒ #f
(real? -2.5+0i) ⇒ #t
(real? -2.5) ⇒ #t
(real? #e1e10) ⇒ #t
(rational? 6/10) ⇒ #t
(rational? 6/3) ⇒ #t
(rational? 2) ⇒ #t
(integer? 3+0i) ⇒ #t
(integer? 3.0) ⇒ #t
(integer? 8/4) ⇒ #t
(number? +nan.0) ⇒ #t
(complex? +nan.0) ⇒ #t
(real? +nan.0) ⇒ #t
(rational? +nan.0) ⇒ #f
(complex? +inf.0) ⇒ #t
(real? -inf.0) ⇒ #t
(rational? -inf.0) ⇒ #f
(integer? -inf.0) ⇒ #f
Note:
number?를 제외하면, 부정확한 수치 객체에 대한 이 타입 술어들의 동작은 신뢰할 수 없어요. 어떤 부정확함도 결과에 영향을 줄 수 있기 때문이에요.
(real-valued? obj) — procedure
(rational-valued? obj) — procedure
(integer-valued? obj) — procedure
이 수치 타입 술어들은 어떤 종류의 인자에도 적용될 수 있어요. real-valued? 프로시저는 객체가 수치 객체이고 =의 의미에서 어떤 실수 수치 객체와 같거나, 또는 객체가 NaN이거나, 실수부가 NaN이고 허수부가 zero?의 의미에서 0인 복소수 수치 객체일 때 #t를 반환해요. rational-valued?와 integer-valued? 프로시저는 객체가 수치 객체이고 =의 의미에서 명명된 타입의 어떤 객체와 같을 때 #t를, 그렇지 않으면 #f를 반환해요.
(real-valued? +nan.0) ⇒ #t
(real-valued? +nan.0+0i) ⇒ #t
(real-valued? -inf.0) ⇒ #t
(real-valued? 3) ⇒ #t
(real-valued? -2.5+0.0i) ⇒ #t
(real-valued? -2.5+0i) ⇒ #t
(real-valued? -2.5) ⇒ #t
(real-valued? #e1e10) ⇒ #t
(rational-valued? +nan.0) ⇒ #f
(rational-valued? -inf.0) ⇒ #f
(rational-valued? 6/10) ⇒ #t
(rational-valued? 6/10+0.0i) ⇒ #t
(rational-valued? 6/10+0i) ⇒ #t
(rational-valued? 6/3) ⇒ #t
(integer-valued? 3+0i) ⇒ #t
(integer-valued? 3+0.0i) ⇒ #t
(integer-valued? 3.0) ⇒ #t
(integer-valued? 3.0+0.0i) ⇒ #t
(integer-valued? 8/4) ⇒ #t
Note: 이 프로시저들은 주어진 수치 객체가 수치 정확도를 잃지 않고 명시된 타입으로 강제 변환될 수 있는지 검사해요. 구체적으로, 이 술어들의 동작은 허수부가 부정확한 0인 복소수 수치 객체에 대한
real?,rational?,integer?의 동작과 다르다는 점이에요.
Note: 부정확한 수치 객체에 대한 이 타입 술어들의 동작은 신뢰할 수 없어요. 어떤 부정확함도 결과에 영향을 줄 수 있기 때문이에요.
(exact? z) — procedure
(inexact? z) — procedure
이 수치 술어들은 양의 정확성에 대한 검사를 제공해요. 어떤 수치 객체에 대해서도, 이 술어들 중 정확히 하나가 참이에요.
(exact? 5) ⇒ #t
(inexact? +inf.0) ⇒ #t
일반적 변환 (11.7.4.2절)
(inexact z) — procedure
(exact z) — procedure
inexact 프로시저는 z의 부정확한 표현을 반환해요. 적절한 타입의 부정확한 수치 객체가 유계 정밀도(bounded precision)를 가지면, 반환되는 값은 인자에 가장 가까운 부정확한 수치 객체예요. 정확한 인자가 합리적으로 가까운 부정확한 동등물이 없으면 조건 타입 &implementation-violation을 가진 예외가 일어날 수 있어요.
Note: 크기가 유한하지만 부정확한 수치로서의 합리적인 유한 근사가 없을 정도로 큰 실수 수치 객체에 대해, 합리적으로 가까운 부정확한 동등물은
+inf.0또는-inf.0일 수 있어요. 비슷하게, 성분들이 유한한 복소수 수치 객체의 부정확한 표현은 무한한 성분을 가질 수 있어요.
exact 프로시저는 z의 정확한 표현을 반환해요. 반환되는 값은 인자에 수치적으로 가장 가까운 정확한 수치 객체예요; 대부분의 경우 이 프로시저의 결과는 인자와 수치적으로 같아야 해요. 부정확한 인자가 합리적으로 가까운 정확한 동등물이 없으면 조건 타입 &implementation-violation을 가진 예외가 일어날 수 있어요.
이 프로시저들은 구현 의존 범위 전반에 걸쳐 정확한 정수 수치 객체와 부정확한 정수 수치 객체 사이의 자연스러운 일대일 대응을 구현해요.
inexact와 exact 프로시저는 멱등(idempotent)이에요.
산술 연산 (11.7.4.3절)
(= z1 z2 z3 ...) — procedure
(< x1 x2 x3 ...) — procedure
(> x1 x2 x3 ...) — procedure
(<= x1 x2 x3 ...) — procedure
(>= x1 x2 x3 ...) — procedure
이 프로시저들은 인자들이 (각각) 같거나, 단조 증가하거나, 단조 감소하거나, 단조 비감소(nondecreasing)하거나, 단조 비증가(nonincreasing)하면 #t를, 그렇지 않으면 #f를 반환해요.
(= +inf.0 +inf.0) ⇒ #t
(= -inf.0 +inf.0) ⇒ #f
(= -inf.0 -inf.0) ⇒ #t
무한대도 NaN도 아닌 어떤 실수 수치 객체 x에 대해:
(> +inf.0 x -inf.0) ⇒ #t
어떤 수치 객체 z에 대해:
(= +nan.0 z) ⇒ #f
어떤 실수 수치 객체 x에 대해:
(> +nan.0 x) ⇒ #f
이 술어들은 이행적(transitive)이어야 해요.
Note: Lisp류 언어에서 이 술어들의 전통적인 구현들은 이행적이지 않아요.
Note: 이 술어들로 부정확한 수치 객체를 비교하는 것이 가능하지만, 작은 부정확함이 결과에 영향을 줄 수 있어 결과가 신뢰할 수 없을 수 있어요; 이는 특히
=와zero?(아래)에서 그렇죠. 의심이 들면 수치 해석 전문가와 상의하세요.
(zero? z) — procedure
(positive? x) — procedure
(negative? x) — procedure
(odd? n) — procedure
(even? n) — procedure
(finite? x) — procedure
(infinite? x) — procedure
(nan? x) — procedure
이 수치 술어들은 수치 객체가 특정 성질을 가지는지 검사하고 #t 또는 #f를 반환해요. zero? 프로시저는 수치 객체가 =의 의미에서 0인지 검사하고, positive?는 0보다 큰지, negative?는 0보다 작은지, odd?는 홀수인지, even?는 짝수인지, finite?는 무한대도 NaN도 아닌지, infinite?는 무한대인지, nan?는 NaN인지 검사해요.
(zero? +0.0) ⇒ #t
(zero? -0.0) ⇒ #t
(zero? +nan.0) ⇒ #f
(positive? +inf.0) ⇒ #t
(negative? -inf.0) ⇒ #t
(positive? +nan.0) ⇒ #f
(negative? +nan.0) ⇒ #f
(finite? +inf.0) ⇒ #f
(finite? 5) ⇒ #t
(finite? 5.0) ⇒ #t
(infinite? 5.0) ⇒ #f
(infinite? +inf.0) ⇒ #t
Note: 위의 술어들과 마찬가지로, 작은 부정확함이 결과에 영향을 줄 수 있어 결과가 신뢰할 수 없을 수 있어요.
(max x1 x2 ...) — procedure
(min x1 x2 ...) — procedure
이 프로시저들은 인자들의 최댓값 또는 최솟값을 반환해요.
(max 3 4) ⇒ 4
(max 3.9 4) ⇒ 4.0
어떤 실수 수치 객체 x에 대해:
(max +inf.0 x) ⇒ +inf.0
(min -inf.0 x) ⇒ -inf.0
Note: 어떤 인자가 부정확하면 결과도 부정확해요(그 프로시저가 부정확함이 결과에 영향을 줄 만큼 크지 않다는 것을 증명할 수 있는 경우라면 예외인데, 이는 드문 구현에서만 가능해요).
min또는max가 혼합된 정확성을 가진 수치 객체들을 비교하는 데 사용되고 결과의 수치적 값이 정확도를 잃지 않고 부정확한 수치 객체로 표현될 수 없으면, 그 프로시저는 조건 타입&implementation-restriction을 가진 예외를 일으킬 수 있어요.
(+ z1 ...) — procedure
(* z1 ...) — procedure
이 프로시저들은 인자들의 합 또는 곱을 반환해요.
(+ 3 4) ⇒ 7
(+ 3) ⇒ 3
(+) ⇒ 0
(+ +inf.0 +inf.0) ⇒ +inf.0
(+ +inf.0 -inf.0) ⇒ +nan.0
(* 4) ⇒ 4
(*) ⇒ 1
(* 5 +inf.0) ⇒ +inf.0
(* -5 +inf.0) ⇒ -inf.0
(* +inf.0 +inf.0) ⇒ +inf.0
(* +inf.0 -inf.0) ⇒ -inf.0
(* 0 +inf.0) ⇒ 0 or +nan.0
(* 0 +nan.0) ⇒ 0 or +nan.0
(* 1.0 0) ⇒ 0 or 0.0
무한대도 NaN도 아닌 어떤 실수 수치 객체 x에 대해:
(+ +inf.0 x) ⇒ +inf.0
(+ -inf.0 x) ⇒ -inf.0
어떤 실수 수치 객체 x에 대해:
(+ +nan.0 x) ⇒ +nan.0
정확한 0이 아닌 어떤 실수 수치 객체 x에 대해:
(* +nan.0 x) ⇒ +nan.0
이 프로시저들 중 어떤 것이 혼합된 비-유리수 실수와 비-실수 복소수 인자에 적용되면, 그것들은 조건 타입 &implementation-restriction을 가진 예외를 일으키거나 미지정 수치 객체를 반환해요.
−0.0을 구별하는 구현들은 다음 예들의 결과와 일치하는 동작을 채택해야 해요:
(+ 0.0 -0.0) ⇒ 0.0
(+ -0.0 0.0) ⇒ 0.0
(+ 0.0 0.0) ⇒ 0.0
(+ -0.0 -0.0) ⇒ -0.0
(- z) — procedure
(- z1 z2 ...) — procedure
인자가 두 개 이상이면 이 프로시저는 인자들의 차를 왼쪽 결합으로 반환해요. 그러나 인자가 하나이면 그것의 덧셈 역원(additive inverse)을 반환해요.
(- 3 4) ⇒ -1
(- 3 4 5) ⇒ -6
(- 3) ⇒ -3
(- +inf.0 +inf.0) ⇒ +nan.0
이 프로시저가 혼합된 비-유리수 실수와 비-실수 복소수 인자에 적용되면, 그것은 조건 타입 &implementation-restriction을 가진 예외를 일으키거나 미지정 수치 객체를 반환해요.
−0.0을 구별하는 구현들은 다음 예들의 결과와 일치하는 동작을 채택해야 해요:
(- 0.0) ⇒ -0.0
(- -0.0) ⇒ 0.0
(- 0.0 -0.0) ⇒ 0.0
(- -0.0 0.0) ⇒ -0.0
(- 0.0 0.0) ⇒ 0.0
(- -0.0 -0.0) ⇒ 0.0
(/ z) — procedure
(/ z1 z2 ...) — procedure
모든 인자가 정확하면 나누는 수들은 모두 0이 아니어야 해요. 인자가 두 개 이상이면 이 프로시저는 인자들의 몫을 왼쪽 결합으로 반환해요. 그러나 인자가 하나이면 그것의 곱셈 역원(multiplicative inverse)을 반환해요.
(/ 3 4 5) ⇒ 3/20
(/ 3) ⇒ 1/3
(/ 0.0) ⇒ +inf.0
(/ 1.0 0) ⇒ +inf.0
(/ -1 0.0) ⇒ -inf.0
(/ +inf.0) ⇒ 0.0
(/ 0 0) &assertion exception
(/ 3 0) &assertion exception
(/ 0 3.5) ⇒ 0.0
(/ 0 0.0) ⇒ +nan.0
(/ 0.0 0) ⇒ +nan.0
(/ 0.0 0.0) ⇒ +nan.0
이 프로시저가 혼합된 비-유리수 실수와 비-실수 복소수 인자에 적용되면, 그것은 조건 타입 &implementation-restriction을 가진 예외를 일으키거나 미지정 수치 객체를 반환해요.
(abs x) — procedure
인자의 절댓값을 반환해요.
(abs -7) ⇒ 7
(abs -inf.0) ⇒ +inf.0
(div-and-mod x1 x2) — procedure
(div x1 x2) — procedure
(mod x1 x2) — procedure
(div0-and-mod0 x1 x2) — procedure
(div0 x1 x2) — procedure
(mod0 x1 x2) — procedure
이 프로시저들은 수론적 정수 나눗셈을 구현하고 11.7.3.1절에서 명시된 대응하는 수학적 연산들의 결과를 반환해요. 각 경우 x1은 무한대도 NaN도 아니어야 하고 x2는 0이 아니어야 해요; 그렇지 않으면 조건 타입 &assertion을 가진 예외가 일어나요.
(div x1 x2) ⇒ x1 div x2
(mod x1 x2) ⇒ x1 mod x2
(div-and-mod x1 x2) ⇒ x1 div x2, x1 mod x2
; two return values
(div0 x1 x2) ⇒ x1 div0 x2
(mod0 x1 x2) ⇒ x1 mod0 x2
(div0-and-mod0 x1 x2) ⇒ x1 div0 x2, x1 mod0 x2
; two return values
(gcd n1 ...) — procedure
(lcm n1 ...) — procedure
이 프로시저들은 인자들의 최대공약수 또는 최소공배수를 반환해요. 결과는 항상 음이 아니에요.
(gcd 32 -36) ⇒ 4
(gcd) ⇒ 0
(lcm 32 -36) ⇒ 288
(lcm 32.0 -36) ⇒ 288.0
(lcm) ⇒ 1
(numerator q) — procedure
(denominator q) — procedure
이 프로시저들은 인자의 분자 또는 분모를 반환해요; 결과는 인자가 최저항(fraction in lowest terms)의 분수로 표현된 것처럼 계산돼요. 분모는 항상 양수예요. 0의 분모는 1로 정의돼요.
(numerator (/ 6 4)) ⇒ 3
(denominator (/ 6 4)) ⇒ 2
(denominator
(inexact (/ 6 4))) ⇒ 2.0
(floor x) — procedure
(ceiling x) — procedure
(truncate x) — procedure
(round x) — procedure
이 프로시저들은 무한대나 NaN이 아닌 부정확한 인자에 대해 부정확한 정수 객체를, 정확한 유리수 인자에 대해 정확한 정수 객체를 반환해요. 그러한 인자에 대해 floor는 x보다 크지 않은 가장 큰 정수 객체를 반환해요. ceiling 프로시저는 x보다 작지 않은 가장 작은 정수 객체를 반환해요. truncate 프로시저는 절댓값이 x의 절댓값보다 크지 않은, x에 가장 가까운 정수 객체를 반환해요. round 프로시저는 x에 가장 가까운 정수 객체를 반환하는데, x가 두 정수 사이의 정확히 중간 값을 나타낼 때는 짝수 쪽으로 반올림해요.
Note: 이 프로시저들 중 하나에 대한 인자가 부정확하면 결과도 부정확해요. 정확한 값이 필요하면 결과를
exact프로시저에 전달해야 해요.
무한대와 NaN은 정수 객체가 아니지만, 이 프로시저들은 인자로 무한대가 주어지면 무한대를, NaN이 주어지면 NaN을 반환해요.
(floor -4.3) ⇒ -5.0
(ceiling -4.3) ⇒ -4.0
(truncate -4.3) ⇒ -4.0
(round -4.3) ⇒ -4.0
(floor 3.5) ⇒ 3.0
(ceiling 3.5) ⇒ 4.0
(truncate 3.5) ⇒ 3.0
(round 3.5) ⇒ 4.0
(round 7/2) ⇒ 4
(round 7) ⇒ 7
(floor +inf.0) ⇒ +inf.0
(ceiling -inf.0) ⇒ -inf.0
(round +nan.0) ⇒ +nan.0
(rationalize x1 x2) — procedure
rationalize 프로시저는 x1과 x2만큼 이하로만 다른 가장 단순한 유리수를 나타내는 수치 객체를 반환해요. 유리수 r1은, r1 = p1/q1이고 r2 = p2/q2(최저항으로)일 때 |p1| ≤ |p2|이고 |q1| ≤ |q2|이면 다른 유리수 r2보다 단순해요. 따라서 3/5는 4/7보다 단순해요. 모든 유리수가 이 순서에서 비교 가능한 것은 아니지만(2/7과 3/5를 생각해보세요) 어떤 구간도 그 구간의 다른 모든 유리수보다 단순한 유리수를 포함해요(더 단순한 2/5가 2/7과 3/5 사이에 있어요). 0 = 0/1이 모든 유리수 중 가장 단순하다는 점에 주목하세요.
(rationalize (exact .3) 1/10) ⇒ 1/3
(rationalize .3 1/10) ⇒ #i1/3 ; approximately
(rationalize +inf.0 3) ⇒ +inf.0
(rationalize +inf.0 +inf.0) ⇒ +nan.0
(rationalize 3 +inf.0) ⇒ 0.0
처음 두 예는 부정확한 실수 수치 객체가 충분한 정밀도를 가지는 구현에서만 성립해요.
(exp z) — procedure
(log z) — procedure
(log z1 z2) — procedure
(sin z) — procedure
(cos z) — procedure
(tan z) — procedure
(asin z) — procedure
(acos z) — procedure
(atan z) — procedure
(atan x1 x2) — procedure
이 프로시저들은 보통의 초월 함수들을 계산해요. exp 프로시저는 z의 밑이 e인 지수를 계산해요. 단일 인자를 가진 log 프로시저는 z의 자연로그를 계산해요(밑이 10인 로그가 아니라); (log z1 z2)는 밑이 z2인 z1의 로그를 계산해요. asin, acos, atan 프로시저는 각각 아크사인, 아크코사인, 아크탄젠트를 계산해요. 두-인자 변형 atan은 (angle (make-rectangular x2 x1))을 계산해요.
기저가 되는 수학적 연산에 대해서는 11.7.3.2절을 참조하세요. 이 프로시저들은 정확한 인자가 주어져도 부정확한 결과를 반환할 수 있어요.
(exp +inf.0) ⇒ +inf.0
(exp -inf.0) ⇒ 0.0
(log +inf.0) ⇒ +inf.0
(log 0.0) ⇒ -inf.0
(log 0) &assertion exception
(log -inf.0) ⇒ +inf.0+3.141592653589793i
; approximately
(atan -inf.0) ⇒ -1.5707963267948965 ; approximately
(atan +inf.0) ⇒ 1.5707963267948965 ; approximately
(log -1.0+0.0i) ⇒ 0.0+3.141592653589793i ; approximately
(log -1.0-0.0i) ⇒ 0.0-3.141592653589793i ; approximately
; if -0.0 is distinguished
(sqrt z) — procedure
z의 주 제곱근(principal square root)을 반환해요. 유리수 z에 대해 결과는 양의 실수부를 가지거나, 실수부가 0이고 허수부가 음이 아니에요. log를 11.7.3.2절에서와 같이 정의하면, (sqrt z)의 값은 e^(log z / 2)로 표현될 수 있어요.
sqrt 프로시저는 정확한 인자가 주어져도 부정확한 결과를 반환할 수 있어요.
(sqrt -5) ⇒ 0.0+2.23606797749979i ; approximately
(sqrt +inf.0) ⇒ +inf.0
(sqrt -inf.0) ⇒ +inf.0i
(exact-integer-sqrt k) — procedure
exact-integer-sqrt 프로시저는 k = s² + r이고 k < (s + 1)²인 두 개의 음이 아닌 정확한 정수 객체 s와 r을 반환해요.
(exact-integer-sqrt 4) ⇒ 2 0
; two return values
(exact-integer-sqrt 5) ⇒ 2 1
; two return values
(expt z1 z2) — procedure
z1을 z2 거듭제곱한 값을 반환해요. 0이 아닌 z1에 대해 이것은 e^(z2·log z1)이에요. 0.0^z는 z = 0.0이면 1.0이고, (real-part z)가 양수이면 0.0이에요. 첫 번째 인자가 0인 다른 경우에는 조건 타입 &implementation-restriction을 가진 예외가 일어나거나 미지정 수치 객체가 반환돼요.
정확한 실수 수치 객체 z1과 정확한 정수 객체 z2에 대해 (expt z1 z2)는 정확한 결과를 반환해야 해요. 다른 모든 z1과 z2 값에 대해 (expt z1 z2)은 z1과 z2가 모두 정확할 때조차 부정확한 결과를 반환할 수 있어요.
(expt 5 3) ⇒ 125
(expt 5 -3) ⇒ 1/125
(expt 5 0) ⇒ 1
(expt 0 5) ⇒ 0
(expt 0 5+.0000312i) ⇒ 0
(expt 0 -5) ⇒ unspecified
(expt 0 -5+.0000312i) ⇒ unspecified
(expt 0 0) ⇒ 1
(expt 0.0 0.0) ⇒ 1.0
(make-rectangular x1 x2) — procedure
(make-polar x3 x4) — procedure
(real-part z) — procedure
(imag-part z) — procedure
(magnitude z) — procedure
(angle z) — procedure
a1, a2, a3, a4가 실수이고 c가 다음이 성립하는 복소수라고 가정해요:
c = a1 + a2·i = a3·e^(i·a4)
그러면, x1, x2, x3, x4가 각각 a1, a2, a3, a4를 나타내는 수치 객체라면, (make-rectangular x1 x2)는 c를 반환하고 (make-polar x3 x4)는 c를 반환해요.
(make-rectangular 1.1 2.2) ⇒ 1.1+2.2i ; approximately
(make-polar 1.1 2.2) ⇒ [email protected] ; approximately
반대로, −π ≤ a4 ≤ π이고 z가 c를 나타내는 수치 객체라면, (real-part z)는 a1을, (imag-part z)는 a2를, (magnitude z)는 a3을, (angle z)는 a4를 반환해요.
(real-part 1.1+2.2i) ⇒ 1.1 ; approximately
(imag-part 1.1+2.2i) ⇒ 2.2i ; approximately
(magnitude [email protected]) ⇒ 1.1 ; approximately
(angle [email protected]) ⇒ 2.2 ; approximately
(angle -1.0) ⇒ 3.141592653589793 ; approximately
(angle -1.0+0.0i) ⇒ 3.141592653589793 ; approximately
(angle -1.0-0.0i) ⇒ -3.141592653589793 ; approximately
; if -0.0 is distinguished
(angle +inf.0) ⇒ 0.0
(angle -inf.0) ⇒ 3.141592653589793 ; approximately
게다가 x1, x2가 x1 또는 x2 중 하나가 무한대가 되도록 하는 값들이라면,
(make-rectangular x1 x2) ⇒ z
(magnitude z) ⇒ +inf.0
make-polar, magnitude, angle 프로시저들은 정확한 인자가 주어져도 부정확한 결과를 반환할 수 있어요.
(angle -1) ⇒ 3.141592653589793 ; approximately
수치 입출력 (11.7.4.4절)
(number->string z) — procedure
(number->string z radix) — procedure
(number->string z radix precision) — procedure
radix는 2, 8, 10, 16 중 하나인 정확한 정수 객체여야 해요. 생략되면 radix는 10으로 기본값이 정해져요. precision이 명시되면, z는 부정확한 복소수 수치 객체여야 하고, precision은 정확한 양의 정수 객체여야 하며, radix는 10이어야 해요. number->string 프로시저는 수치 객체와 기수를 받아서, 주어진 기수에서 주어진 수치 객체의 외부 표현을 문자열로 반환하는데, 다음과 같이:
(let ((number z) (radix radix))
(eqv? (string->number
(number->string number radix)
radix)
number))
가 참이 되도록 해요. 이 표현식을 참으로 만들 수 있는 가능한 결과가 없으면 조건 타입 &implementation-restriction을 가진 예외가 일어나요.
Note: 오류 사례는
z가 복소수 수치 객체가 아니거나, 비-유리수 실수부 또는 허수부를 가진 복소수 수치 객체일 때만 발생할 수 있어요.
precision이 명시되면, 무한대나 NaN이 아닌 결과의 부정확한 실수 성분들의 표현은 명시적인 <mantissa width> p를 명시하고, p는 위의 표현식이 참이 되게 하는 가장 작은 p ≥ precision이에요.
z가 부정확하고 radix가 10이며, 위의 표현식과 조건이 소수점을 포함하는 결과로 충족될 수 있으면, 결과는 소수점을 포함하고 위의 표현식과 조건을 참으로 만드는 데 필요한 최소 개수의 자릿수(지수, 끝의 0들, 가수 너비는 제외)로 표현돼요 [4, 7]; 그렇지 않으면 결과의 형식은 미지정이에요.
number->string이 반환하는 결과는 명시적인 기수 접두사(radix prefix)를 결코 포함하지 않아요.
(string->number string) — procedure
(string->number string radix) — procedure
주어진 문자열이 표현하는, 최대한 정밀한 표현을 가진 수치 객체를 반환해요. radix는 2, 8, 10, 16 중 하나인 정확한 정수 객체여야 해요. 제공되면 radix는 문자열 안의 명시적인 기수 접두사(예: "#o177")로 덮어쓸 수 있는 기본 기수예요. radix가 제공되지 않으면 기본 기수는 10이에요. string이 수치 객체에 대한 구문적으로 유효한 표기이거나 분모가 0인 유리수 수치 객체에 대한 표기가 아니면 string->number는 #f를 반환해요.
(string->number "100") ⇒ 100
(string->number "100" 16) ⇒ 256
(string->number "1e2") ⇒ 100.0
(string->number "0/0") ⇒ #f
(string->number "+inf.0") ⇒ +inf.0
(string->number "-inf.0") ⇒ -inf.0
(string->number "+nan.0") ⇒ +nan.0
Note:
string->number프로시저는 항상 수치 객체 또는#f를 반환해요; 결코 예외를 일으키지 않아요.