Rational 클래스

Rational 클래스

유리수(rational number)는 정수 한 쌍으로 표현할 수 있어요: a/b (b>0). 여기서 a는 분자(numerator), b는 분모(denominator)예요. Integer a는 수학적으로 유리수 a/1과 같아요.

출처: Ruby 3.3 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

rat * numeric → numeric

곱셈을 수행해요.

Rational(2, 3)  * Rational(2, 3)   #=> (4/9)
Rational(900)   * Rational(1)      #=> (900/1)
Rational(-2, 9) * Rational(-9, 2)  #=> (1/1)
Rational(9, 8)  * 4                #=> (9/2)
Rational(20, 9) * 9.8              #=> 21.77777777777778

rat ** numeric → numeric

거듭제곱을 수행해요.

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

rat + numeric → numeric

덧셈을 수행해요.

Rational(2, 3)  + Rational(2, 3)   #=> (4/3)
Rational(900)   + Rational(1)      #=> (901/1)
Rational(-2, 9) + Rational(-9, 2)  #=> (-85/18)
Rational(9, 8)  + 4                #=> (41/8)
Rational(20, 9) + 9.8              #=> 12.022222222222222

rat - numeric → numeric

뺄셈을 수행해요.

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

-rat → rational

rat의 부호를 바꿔요(negate).

rat / numeric → numeric

나눗셈을 수행해요. quo로도 불려요.

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

rational <=> numeric → -1, 0, +1, or nil

rationalnumeric보다 작은지, 같은지, 큰지에 따라 -1, 0, +1을 반환해요. 비교할 수 없는 두 값이면 nil을 반환해요.

Rational(2, 3) <=> Rational(2, 3)  #=> 0
Rational(5)    <=> 5               #=> 0
Rational(2, 3) <=> Rational(1, 3)  #=> 1
Rational(1, 3) <=> 1               #=> -1
Rational(1, 3) <=> 0.3             #=> 1

Rational(1, 3) <=> "0.3"           #=> nil

rat == object → true or false

ratobject와 수치적으로 같으면 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의 절댓값을 반환해요. magnitude로도 불려요.

(1/2r).abs    #=> (1/2)
(-1/2r).abs   #=> (1/2)

as_json(*)

Rational#as_jsonRational.json_create 메서드는 Rational 객체를 직렬화/역직렬화하는 데 쓸 수 있어요. Rational#as_jsonself를 직렬화해서 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

Rational('-123.456').floor(+1).to_f  #=> -123.5
Rational('-123.456').floor(-1)       #=> -130

hash()

이 객체의 해시 값을 반환해요.

inspect → string

값을 검사용(inspection) 문자열로 반환해요.

Rational(2).inspect      #=> "(2/1)"
Rational(-8, 6).inspect  #=> "(-4/3)"
Rational('1/2').inspect  #=> "(1/2)"

magnitude → rational

rat의 절댓값을 반환해요. abs의 별칭이에요.

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(numeric) → numeric

나눗셈을 수행해요. /의 별칭이에요.

rationalize → self, rationalize(eps) → rational

선택 인자 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

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_d(precision) → bigdecimal

값을 BigDecimal로 반환해요. 필수 precision 매개변수는 결과의 유효 자릿수를 정하는 데 쓰여요.

require 'bigdecimal'
require 'bigdecimal/util'

Rational(22, 7).to_d(3)   # => 0.314e1

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

Rational('-123.456').truncate(+1).to_f  #=> -123.4
Rational('-123.456').truncate(-1)       #=> -120