Rational 클래스
Rational 클래스
유리수(rational number)는 두 정수의 쌍, 즉 a/b (b>0)로 나타낼 수 있는데, 여기서 a를 분자(numerator), b를 분모(denominator)라고 불러요. 수학적으로 정수 a는 유리수 a/1과 같아요.
출처: Ruby 4.0 API
본문
Rational 객체는 두 가지로 만들 수 있어요.
- 유리수 리터럴로 직접 만들기
Rational메서드로 특정 객체를 변환하기
Rational(1) #=> (1/1)
Rational(2, 3) #=> (2/3)
Rational(4, -6) #=> (-2/3) # Reduced.
3.to_r #=> (3/1)
2/3r #=> (2/3)
부동소수점 수나 문자열에서도 유리수 객체를 만들 수 있어요.
Rational(0.3) #=> (5404319552844595/18014398509481984)
Rational('0.3') #=> (3/10)
Rational('2/3') #=> (2/3)
0.3.to_r #=> (5404319552844595/18014398509481984)
'0.3'.to_r #=> (3/10)
'2/3'.to_r #=> (2/3)
0.3.rationalize #=> (3/10)
유리수 객체는 정확한(exact) 수예요. 그래서 반올림 오류 없이 프로그램을 작성하는 데 도움이 돼요.
10.times.inject(0) {|t| t + 0.1 } #=> 0.9999999999999999
10.times.inject(0) {|t| t + Rational('0.1') } #=> (1/1)
다만, 표현식 안에 부정확한(inexact) 성분(숫자 값이나 연산)이 섞이면 결과도 부정확해져요.
Rational(10) / 3 #=> (10/3)
Rational(10) / 3.0 #=> 3.3333333333333335
Rational(-8) ** Rational(1, 3)
#=> (1.0000000000000002+1.7320508075688772i)
Public Class Methods
json_create(object)
as_json을 참고하세요. JSON에서 Rational 객체를 복원해요.
Public Instance Methods
self * other → numeric
self와 other의 곱을 반환해요:
Rational(9, 8) * 4 #=> (9/2)
Rational(20, 9) * 9.8 #=> 21.77777777777778
Rational(9, 8) * Complex(1, 2) # => ((9/8)+(9/4)*i)
Rational(2, 3) * Rational(2, 3) #=> (4/9)
Rational(900) * Rational(1) #=> (900/1)
Rational(-2, 9) * Rational(-9, 2) #=> (1/1)
self ** exponent → numeric
self를 exponent만큼 거듭제곱한 값을 반환해요:
Rational(2) ** Rational(3) #=> (8/1)
Rational(10) ** -2 #=> (1/100)
Rational(10) ** -2.0 #=> 0.01
Rational(-4) ** Rational(1, 2) #=> (0.0+2.0i)
Rational(1, 2) ** 0 #=> (1/1)
Rational(1, 2) ** 0.0 #=> 1.0
self + other → numeric
self와 other의 합을 반환해요:
Rational(2, 3) + 0 # => (2/3)
Rational(2, 3) + 1 # => (5/3)
Rational(2, 3) + -1 # => (-1/3)
Rational(2, 3) + Complex(1, 0) # => ((5/3)+0i)
Rational(2, 3) + Rational(1, 1) # => (5/3)
Rational(2, 3) + Rational(3, 2) # => (13/6)
Rational(2, 3) + Rational(3.0, 2.0) # => (13/6)
Rational(2, 3) + Rational(3.1, 2.1) # => (30399297484750849/14186338826217063)
Float가 포함된 계산은 결과가 부정확할 수 있어요 (Float#+ 참고):
Rational(2, 3) + 1.0 # => 1.6666666666666665
Rational(2, 3) + Complex(1.0, 0.0) # => (1.6666666666666665+0.0i)
self - other → numeric
self와 other의 차를 반환해요:
Rational(2, 3) - Rational(2, 3) #=> (0/1)
Rational(900) - Rational(1) #=> (899/1)
Rational(-2, 9) - Rational(-9, 2) #=> (77/18)
Rational(9, 8) - 4 #=> (-23/8)
Rational(20, 9) - 9.8 #=> -7.577777777777778
-self → rational
self를 부정(negate)한 값을 반환해요:
-(1/3r) # => (-1/3)
-(-1/3r) # => (1/3)
self / other → numeric
self와 other의 몫을 반환해요:
Rational(2, 3) / Rational(2, 3) #=> (1/1)
Rational(900) / Rational(1) #=> (900/1)
Rational(-2, 9) / Rational(-9, 2) #=> (4/81)
Rational(9, 8) / 4 #=> (9/32)
Rational(20, 9) / 9.8 #=> 0.22675736961451246
self <=> other → -1, 0, 1, or nil
self와 other를 비교해요. 반환값은 다음과 같아요:
-1: self가 other보다 작을 때0: 두 값이 같을 때1: self가 other보다 클 때nil: 두 값을 비교할 수 없을 때
Rational(2, 3) <=> Rational(4, 3) # => -1
Rational(2, 1) <=> Rational(2, 1) # => 0
Rational(2, 1) <=> 2 # => 0
Rational(2, 1) <=> 2.0 # => 0
Rational(2, 1) <=> Complex(2, 0) # => 0
Rational(4, 3) <=> Rational(2, 3) # => 1
Rational(4, 3) <=> :foo # => nil
Rational 클래스는 Comparable 모듈을 포함하는데, 그 모듈의 각 메서드는 비교에 Rational#<=>를 사용해요.
rat == object → true or false
rat이 object와 수치상 같으면 true를 반환해요:
Rational(2, 3) == Rational(2, 3) #=> true
Rational(5) == 5 #=> true
Rational(0) == 0.0 #=> true
Rational('1/3') == 0.33 #=> false
Rational('1/2') == '1/2' #=> false
abs → rational
rat의 절댓값을 반환해요:
(1/2r).abs #=> (1/2)
(-1/2r).abs #=> (1/2)
as_json(*)
Rational#as_json과 Rational.json_create 메서드는 Rational 객체를 직렬화/역직렬화하는 데 쓸 수 있어요. Marshal을 참고하세요. Rational#as_json은 self를 직렬화해서 2-요소 해시를 반환해요:
require 'json/add/rational'
x = Rational(2, 3).as_json
# => {"json_class"=>"Rational", "n"=>2, "d"=>3}
JSON.create는 그런 해시를 역직렬화해서 Rational 객체를 반환해요:
Rational.json_create(x)
# => (2/3)
ceil([ndigits]) → integer or rational
rat보다 크거나 같은 가장 작은 수를 ndigits 자리(소수점 아래, 기본 0)의 정밀도로 반환해요. 정밀도가 음수면 최소 ndigits.abs개의 뒤쪽 0을 가진 정수를 반환해요. ndigits가 양수면 유리수를, 그 외에는 정수를 반환해요.
Rational(3).ceil #=> 3
Rational(2, 3).ceil #=> 1
Rational(-3, 2).ceil #=> -1
# decimal - 1 2 3 . 4 5 6
# ^ ^ ^ ^ ^ ^
# precision -3 -2 -1 0 +1 +2
Rational('-123.456').ceil(+1).to_f #=> -123.4
Rational('-123.456').ceil(-1) #=> -120
denominator → integer
분모(항상 양수)를 반환해요:
Rational(7).denominator #=> 1
Rational(7, 1).denominator #=> 1
Rational(9, -4).denominator #=> 4
Rational(-2, -10).denominator #=> 5
fdiv(numeric) → float
나눗셈을 수행하고 Float로 값을 반환해요:
Rational(2, 3).fdiv(1) #=> 0.6666666666666666
Rational(2, 3).fdiv(0.5) #=> 1.3333333333333333
Rational(2).fdiv(3) #=> 0.6666666666666666
floor([ndigits]) → integer or rational
rat보다 작거나 같은 가장 큰 수를 ndigits 자리(기본 0)의 정밀도로 반환해요. 정밀도가 음수면 최소 ndigits.abs개의 뒤쪽 0을 가진 정수를 반환해요. ndigits가 양수면 유리수를, 그 외에는 정수를 반환해요.
Rational(3).floor #=> 3
Rational(2, 3).floor #=> 0
Rational(-3, 2).floor #=> -2
# decimal - 1 2 3 . 4 5 6
# ^ ^ ^ ^ ^ ^
# precision -3 -2 -1 0 +1 +2
Rational('-123.456').floor(+1).to_f #=> -123.5
Rational('-123.456').floor(-1) #=> -130
hash()
이 객체의 해시 값을 반환해요.
inspect → string
검사용 문자열로 값을 반환해요:
Rational(2).inspect #=> "(2/1)"
Rational(-8, 6).inspect #=> "(-4/3)"
Rational('1/2').inspect #=> "(1/2)"
magnitude → rational
rat의 절댓값을 반환해요:
(1/2r).abs #=> (1/2)
(-1/2r).abs #=> (1/2)
negative? → true or false
rat이 0보다 작으면 true를 반환해요.
numerator → integer
분자를 반환해요:
Rational(7).numerator #=> 7
Rational(7, 1).numerator #=> 7
Rational(9, -4).numerator #=> -9
Rational(-2, -10).numerator #=> 1
positive? → true or false
rat이 0보다 크면 true를 반환해요.
quo()
quo는 나눗셈을 수행해요. Rational#/과 관련된 메서드예요.
rationalize → self
선택 인자 eps가 주어지면 값의 더 단순한 근사치를 반환하고(rat-|eps| <= result <= rat+|eps|), 주어지지 않으면 self를 반환해요:
r = Rational(5033165, 16777216)
r.rationalize #=> (5033165/16777216)
r.rationalize(Rational('0.01')) #=> (3/10)
r.rationalize(Rational('0.1')) #=> (1/3)
round([ndigits] [, half: mode]) → integer or rational
rat을 ndigits 자리(기본 0)의 정밀도로 가장 가까운 값으로 반올림해 반환해요. 정밀도가 음수면 최소 ndigits.abs개의 뒤쪽 0을 가진 정수를 반환해요. ndigits가 양수면 유리수를, 그 외에는 정수를 반환해요.
Rational(3).round #=> 3
Rational(2, 3).round #=> 1
Rational(-3, 2).round #=> -2
# decimal - 1 2 3 . 4 5 6
# ^ ^ ^ ^ ^ ^
# precision -3 -2 -1 0 +1 +2
Rational('-123.456').round(+1).to_f #=> -123.5
Rational('-123.456').round(-1) #=> -120
선택 인자 half 키워드는 Float#round와 비슷하게 동작해요:
Rational(25, 100).round(1, half: :up) #=> (3/10)
Rational(25, 100).round(1, half: :down) #=> (1/5)
Rational(25, 100).round(1, half: :even) #=> (1/5)
Rational(35, 100).round(1, half: :up) #=> (2/5)
Rational(35, 100).round(1, half: :down) #=> (3/10)
Rational(35, 100).round(1, half: :even) #=> (2/5)
Rational(-25, 100).round(1, half: :up) #=> (-3/10)
Rational(-25, 100).round(1, half: :down) #=> (-1/5)
Rational(-25, 100).round(1, half: :even) #=> (-1/5)
to_f → float
값을 Float로 반환해요:
Rational(2).to_f #=> 2.0
Rational(9, 4).to_f #=> 2.25
Rational(-3, 4).to_f #=> -0.75
Rational(20, 3).to_f #=> 6.666666666666667
to_i → integer
절삭(truncate)한 값을 정수로 반환해요. Rational#truncate와 동일해요:
Rational(2, 3).to_i #=> 0
Rational(3).to_i #=> 3
Rational(300.6).to_i #=> 300
Rational(98, 71).to_i #=> 1
Rational(-31, 2).to_i #=> -15
to_json(*args)
self를 나타내는 JSON 문자열을 반환해요:
require 'json/add/rational'
puts Rational(2, 3).to_json
출력:
{"json_class":"Rational","n":2,"d":3}
to_r → self
self를 반환해요:
Rational(2).to_r #=> (2/1)
Rational(-8, 6).to_r #=> (-4/3)
to_s → string
값을 문자열로 반환해요:
Rational(2).to_s #=> "2/1"
Rational(-8, 6).to_s #=> "-4/3"
Rational('1/2').to_s #=> "1/2"
truncate([ndigits]) → integer or rational
rat을 ndigits 자리(기본 0)의 정밀도로 0 방향으로 절삭해서 반환해요. 정밀도가 음수면 최소 ndigits.abs개의 뒤쪽 0을 가진 정수를 반환해요. ndigits가 양수면 유리수를, 그 외에는 정수를 반환해요.
Rational(3).truncate #=> 3
Rational(2, 3).truncate #=> 0
Rational(-3, 2).truncate #=> -1
# decimal - 1 2 3 . 4 5 6
# ^ ^ ^ ^ ^ ^
# precision -3 -2 -1 0 +1 +2
Rational('-123.456').truncate(+1).to_f #=> -123.4
Rational('-123.456').truncate(-1) #=> -120