Float 클래스

Float 클래스 (Float)

Float 객체는 네이티브 아키텍처의 double-precision 부동소수점 표현을 사용해서, 때로는 정확하지 않은(inexact) 실수를 나타내요.

부동소수점은 다른 산술 체계를 가지며 정확하지 않은 숫자예요. 그래서 그 까다로운 특성을 알아야 해요. 참고할 만한 자료:

  • docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
  • github.com/rdp/ruby_tutorials_core/wiki/Ruby-Talk-FAQ#-why-are-rubys-floats-imprecise
  • en.wikipedia.org/wiki/Floating_point#Accuracy_problems

Float 객체는 다음으로 명시적으로 만들 수 있어요.

  • 부동소수점 리터럴
  • Float 메서드로 특정 객체를 변환

FloatNumeric 클래스에서 상속받아요. 여기서는 Float가 직접 제공하는 메서드들을 살펴볼게요: 질의(querying), 비교(comparing), 변환(converting).

출처: Ruby 3.3 API

본문

Querying (질의)

  • finite?self가 유한한지
  • hashself의 정수 해시 코드
  • infinite?self가 무한인지
  • nan?self가 NaN(not-a-number)인지

Comparing (비교)

  • <, <=, <=>, ==(별칭 ===, eql?), >, >= — 다른 값과의 수치 비교

Converting (변환)

  • %(별칭 modulo), *, **, +, -, / — 산술 연산
  • ceil, coerce, divmod, fdiv, floor, next_float, prev_float, quo, round, to_i(별칭 to_int), to_s(별칭 inspect), truncate — 반올림·내림·변환

상수 (Constants)

  • DIG — double-precision 부동소수점에서 유의미한 십진 자릿수의 최소값. 보통 15.
  • EPSILON — 1과 1보다 큰 가장 작은 double-precision 부동소수점의 차이. 보통 2.2204460492503131e-16.
  • INFINITY — 양의 무한대를 나타내는 표현식
  • MANT_DIG — double 데이터 타입의 base 자릿수. 보통 53.
  • MAX — double-precision 부동소수점에서 가능한 가장 큰 정수. 보통 1.7976931348623157e+308.
  • MAX_10_EXP — 이 값으로 10을 거듭제곱한 것(빼기 1)이 가능한 가장 큰 양의 지수. 보통 308.
  • MAX_EXP — double-precision 부동소수점의 가능한 최대 지수값. 보통 1024.
  • MIN — double-precision 부동소수점에서 가장 작은 양의 정규화된 수. 보통 2.2250738585072014e-308. 플랫폼이 비정규화(denormalized) 수를 지원하면 0Float::MIN 사이에 수가 있어요. 0.0.next_float는 비정규화 수를 포함한 가장 작은 양의 부동소수점 수를 돌려줘요.
  • MIN_10_EXP — 이 값으로 10을 거듭제곱한 것(빼기 1)이 가능한 가장 작은 음의 지수. 보통 -307.
  • MIN_EXP — double-precision 부동소수점의 가능한 최소 지수값. 보통 -1021.
  • NAN — "not a number"인 값을 나타내는 표현식
  • RADIX — 부동소수점의 base. 대부분 시스템에서 2(십진 10을 표현).

#% (Public Instance Method)

self % other → float — selfother로 나눈 나머지를 float로 돌려줘요. float f와 실수 r에 대해 다음 표현은 동등해요.

f % r
f-r*(f/r).floor
f.divmod(r)[1]
10.0 % 2              # => 0.0
10.0 % 3              # => 1.0
10.0 % 4              # => 2.0

10.0 % -2             # => 0.0
10.0 % -3             # => -2.0
10.0 % -4             # => -2.0

10.0 % 4.0            # => 2.0
10.0 % Rational(4, 1) # => 2.0

modulo의 별칭이에요.

#* (Public Instance Method)

self * other → numeric — selfother의 곱인 새 Float를 돌려줘요.

f = 3.14
f * 2              # => 6.28
f * 2.0            # => 6.28
f * Rational(1, 2) # => 1.57
f * Complex(2, 0)  # => (6.28+0.0i)

#** (Public Instance Method)

self ** other → numeric — selfother의 거듭제곱으로 올려요.

f = 3.14
f ** 2              # => 9.8596
f ** -2             # => 0.1014239928597509
f ** 2.1            # => 11.054834900588839
f ** Rational(2, 1) # => 9.8596
f ** Complex(2, 0)  # => (9.8596+0i)

#+ (Public Instance Method)

self + other → numeric — selfother의 합인 새 Float를 돌려줘요.

f = 3.14
f + 1                 # => 4.140000000000001
f + 1.0               # => 4.140000000000001
f + Rational(1, 1)    # => 4.140000000000001
f + Complex(1, 0)     # => (4.140000000000001+0i)

#- (Public Instance Method)

self - other → numeric — selfother의 차인 새 Float를 돌려줘요.

f = 3.14
f - 1                 # => 2.14
f - 1.0               # => 2.14
f - Rational(1, 1)    # => 2.14
f - Complex(1, 0)     # => (2.14+0i)

#-@ (Public Instance Method)

-float → float — 부호를 바꾼 self를 돌려줘요.

#/ (Public Instance Method)

self / other → numeric — selfother로 나눈 결과인 새 Float를 돌려줘요.

f = 3.14
f / 2              # => 1.57
f / 2.0            # => 1.57
f / Rational(2, 1) # => 1.57
f / Complex(2, 0)  # => (1.57+0.0i)

#< (Public Instance Method)

self < othertrue 또는 falseself가 수치적으로 other보다 작으면 true를 돌려줘요.

2.0 < 3              # => true
2.0 < 3.0            # => true
2.0 < Rational(3, 1) # => true
2.0 < 2.0            # => false

Float::NAN < Float::NAN은 구현 의존적인 값을 돌려줘요.

#<= (Public Instance Method)

self <= othertrue 또는 falseself가 수치적으로 other보다 작거나 같으면 true.

2.0 <= 3              # => true
2.0 <= 3.0            # => true
2.0 <= Rational(3, 1) # => true
2.0 <= 2.0            # => true
2.0 <= 1.0            # => false

#<=> (Public Instance Method)

self <=> other → -1, 0, +1 또는 nil — selfother의 수치 관계에 따라 값을 돌려줘요.

  • -1: selfother보다 작을 때
  • 0: selfother와 같을 때
  • 1: selfother보다 클 때
  • nil: 두 값이 비교 불가(commensurate하지 않을) 때
2.0 <=> 2              # => 0
2.0 <=> 2.0            # => 0
2.0 <=> Rational(2, 1) # => 0
2.0 <=> Complex(2, 0)  # => 0
2.0 <=> 1.9            # => 1
2.0 <=> 2.1            # => -1
2.0 <=> 'foo'          # => nil

이것은 Comparable 모듈의 테스트 기반이에요.

#== (Public Instance Method)

self == othertrue 또는 falseotherself와 같은 값이면 true, 아니면 false.

2.0 == 2              # => true
2.0 == 2.0            # => true
2.0 == Rational(2, 1) # => true
2.0 == Complex(2, 0)  # => true

관련: Float#eql?(otherFloat여야 함). ===의 별칭이에요.

#> (Public Instance Method)

self > othertrue 또는 falseself가 수치적으로 other보다 크면 true.

2.0 > 1              # => true
2.0 > 1.0            # => true
2.0 > Rational(1, 2) # => true
2.0 > 2.0            # => false

#>= (Public Instance Method)

self >= othertrue 또는 falseself가 수치적으로 other보다 크거나 같으면 true.

2.0 >= 1              # => true
2.0 >= 1.0            # => true
2.0 >= Rational(1, 2) # => true
2.0 >= 2.0            # => true
2.0 >= 2.1            # => false

#abs (Public Instance Method)

abs → float — self의 절댓값을 돌려줘요.

(-34.56).abs # => 34.56
-34.56.abs   # => 34.56
34.56.abs    # => 34.56

#arg (Public Instance Method)

arg → 0 또는 Math::PIself가 양수면 0, 아니면 Math::PI를 돌려줘요. 별칭: angle, phase.

#ceil (Public Instance Method)

ceil(ndigits = 0) → float 또는 integer — self보다 크거나 같은 가장 작은 수를 ndigits 십진 자릿수 정밀도로 돌려줘요. ndigits가 양수면 소수점 아래 ndigits 자릿수의 float, 그 외에는 최소 ndigits.abs개의 끝자리 0을 가진 정수를 돌려줘요.

f = 12345.6789
f.ceil(1) # => 12345.7
f.ceil(3) # => 12345.679
f = -12345.6789
f.ceil(1) # => -12345.6
f.ceil(3) # => -12345.678

f = 12345.6789
f.ceil(0)  # => 12346
f.ceil(-3) # => 13000
f = -12345.6789
f.ceil(0)  # => -12345
f.ceil(-3) # => -12000

부동소수점 산술의 제한된 정밀도 때문에 예상 밖의 결과가 날 수 있다는 점을 유의하세요.

(2.1 / 0.7).ceil  #=> 4 (!)

#coerce (Public Instance Method)

coerce(other) → array — otherFloat로 변환한 값과 self를 담은 2-요소 배열을 돌려줘요. 타입 변환에 실패하면 예외가 발생해요.

f = 3.14                 # => 3.14
f.coerce(2)              # => [2.0, 3.14]
f.coerce(2.0)            # => [2.0, 3.14]
f.coerce(Rational(1, 2)) # => [0.5, 3.14]
f.coerce(Complex(1, 0))  # => [1.0, 3.14]

#denominator (Public Instance Method)

denominator → integer — 분모(항상 양수)를 돌려줘요. 결과는 머신 의존적이에요. (Float#numerator 참고)

#divmod (Public Instance Method)

divmod(other) → array — q = (self/other).floor(몫), r = self % other(나머지)인 2-요소 배열 [q, r]을 돌려줘요.

11.0.divmod(4)              # => [2, 3.0]
11.0.divmod(-4)             # => [-3, -1.0]
-11.0.divmod(4)             # => [-3, 1.0]
-11.0.divmod(-4)            # => [2, -3.0]

12.0.divmod(4)              # => [3, 0.0]
13.0.divmod(4.0)            # => [3, 1.0]
13.0.divmod(Rational(4, 1)) # => [3, 1.0]

#eql? (Public Instance Method)

eql?(other)true 또는 falseotherself와 같은 값을 가진 Float이면 true, 아니면 false.

2.0.eql?(2.0)            # => true
2.0.eql?(1.0)            # => false
2.0.eql?(1)              # => false
2.0.eql?(Rational(2, 1)) # => false
2.0.eql?(Complex(2, 0))  # => false

관련: Float#==(타입 변환 수행).

#fdiv

fdivquo의 별칭이에요.

#finite? (Public Instance Method)

finite?true 또는 falseselfInfinity, -Infinity, NaN이 아니면 true.

f = 2.0      # => 2.0
f.finite?    # => true
f = 1.0/0.0  # => Infinity
f.finite?    # => false
f = -1.0/0.0 # => -Infinity
f.finite?    # => false
f = 0.0/0.0  # => NaN
f.finite?    # => false

#floor (Public Instance Method)

floor(ndigits = 0) → float 또는 integer — self보다 작거나 같은 가장 큰 수를 ndigits 십진 자릿수 정밀도로 돌려줘요.

f = 12345.6789
f.floor(1) # => 12345.6
f.floor(3) # => 12345.678
f = -12345.6789
f.floor(1) # => -12345.7
f.floor(3) # => -12345.679

f = 12345.6789
f.floor(0)  # => 12345
f.floor(-3) # => 12000
f = -12345.6789
f.floor(0)  # => -12346
f.floor(-3) # => -13000
(0.3 / 0.1).floor  #=> 2 (!)

#hash

hash → integer — self의 정수 해시 값. (Object#hash 참고)

#infinite? (Public Instance Method)

infinite? → -1, 1 또는 nil — selfInfinity면 1, -Infinity면 -1, 그 외에는 nil.

f = 1.0/0.0  # => Infinity
f.infinite?  # => 1
f = -1.0/0.0 # => -Infinity
f.infinite?  # => -1
f = 1.0      # => 1.0
f.infinite?  # => nil
f = 0.0/0.0  # => NaN
f.infinite?  # => nil

#magnitude

magnitude()abs와 같은 값(절댓값)을 돌려줘요.

#nan?

nan?true 또는 falseself가 NaN이면 true.

f = -1.0     #=> -1.0
f.nan?       #=> false
f = 0.0/0.0  #=> NaN
f.nan?       #=> true

#negative?

negative?true 또는 falseself가 0보다 작으면 true.

#next_float (Public Instance Method)

next_float → float — 표현 가능한 다음으로 큰 Float를 돌려줘요.

f = 0.0      # 0x0000000000000000
f.next_float # 0x0000000000000001

f = 0.01     # 0x3f847ae147ae147b
f.next_float # 0x3f847ae147ae147c

0.01.next_float    # => 0.010000000000000002
1.0.next_float     # => 1.0000000000000002
100.0.next_float   # => 100.00000000000001

#numerator (Public Instance Method)

numerator → integer — 분자를 돌려줘요. 결과는 머신 의존적이에요.

n = 0.3.numerator    #=> 5404319552844595
d = 0.3.denominator  #=> 18014398509481984
n.fdiv(d)            #=> 0.3

#positive?

positive?true 또는 falseself가 0보다 크면 true.

#prev_float (Public Instance Method)

prev_float → float — 표현 가능한 다음으로 작은 Float를 돌려줘요.

0.01.prev_float   # => 0.009999999999999998
1.0.prev_float    # => 0.9999999999999999
100.0.prev_float  # => 99.99999999999999

#quo (Public Instance Method)

quo(other) → numeric — selfother로 나눈 몫을 돌려줘요. fdiv의 별칭이에요.

f = 3.14
f.quo(2)              # => 1.57
f.quo(-2)             # => -1.57
f.quo(Rational(2, 1)) # => 1.57
f.quo(Complex(2, 0))  # => (1.57+0.0i)

#rationalize (Public Instance Method)

rationalize([eps]) → rational — 값의 더 간단한 근사를 돌려줘요(flt-|eps| <= result <= flt+|eps|). eps를 안 주면 자동으로 선택돼요.

0.3.rationalize          #=> (3/10)
1.333.rationalize        #=> (1333/1000)
1.333.rationalize(0.01)  #=> (4/3)

#round (Public Instance Method)

round(ndigits = 0, half: :up]) → integer 또는 float — selfndigits 십진 자릿수 정밀도의 가장 가까운 값으로 반올림해요. half 키워드 인자를 주고 self가 두 후보 값의 중간이면 그 값에 따라 반올림해요.

  • :up 또는 nil: 0에서 멀어지는 방향(2.5.round(half: :up) #=> 3)
  • :down: 0 쪽으로(2.5.round(half: :down) #=> 2)
  • :even: 마지막 0이 아닌 자릿수가 짝수인 후보 쪽으로(2.5.round(half: :even) #=> 2, 3.5.round(half: :even) #=> 4)

half 값이 유효하지 않으면 예외가 발생해요.

#to_d (Public Instance Method)

to_d → bigdecimal, to_d(precision) → bigdecimal — float 값을 BigDecimal로 돌려줘요. precision 파라미터는 결과의 유효 자릿수를 결정해요. 0이면 자동 결정(기본 0).

require 'bigdecimal'
require 'bigdecimal/util'

0.5.to_d         # => 0.5e0
1.234.to_d       # => 0.1234e1
1.234.to_d(2)    # => 0.12e1

#to_f

to_f → self — self(이미 Float)를 돌려줘요.

#to_i (Public Instance Method)

to_i → integer — selfInteger로 잘라낸(truncate) 값을 돌려줘요. to_int의 별칭이에요.

1.2.to_i    # => 1
(-1.2).to_i # => -1

(0.3 / 0.1).to_i  # => 2 (!)

#to_r (Public Instance Method)

to_r → rational — 값을 유리수로 돌려줘요.

2.0.to_r    #=> (2/1)
2.5.to_r    #=> (5/2)
-0.75.to_r  #=> (-3/4)
0.0.to_r    #=> (0/1)
0.3.to_r    #=> (5404319552844595/18014398509481984)

주의: 0.3.to_r"0.3".to_r과 같지 않아요. 후자는 "3/10".to_r과 동등하지만 전자는 그렇지 않아요.

0.3.to_r   == 3/10r  #=> false
"0.3".to_r == 3/10r  #=> true

#to_s (Public Instance Method)

to_s → string — self의 표현을 담은 문자열을 돌려줘요. 값에 따라 고정소수점 숫자, "scientific notation"(지수를 포함), 'Infinity', '-Infinity', 'NaN'이 될 수 있어요. inspect의 별칭이에요.

3.14.to_s          # => "3.14"
(10.1**50).to_s    # => "1.644631821843879e+50"
(10.1**500).to_s   # => "Infinity"
(-10.1**500).to_s  # => "-Infinity"
(0.0/0.0).to_s     # => "NaN"

#truncate (Public Instance Method)

truncate(ndigits = 0) → float 또는 integer — self를(0 쪽으로) ndigits 십진 자릿수 정밀도로 잘라요.

f = 12345.6789
f.truncate(1) # => 12345.6
f.truncate(3) # => 12345.678
f = -12345.6789
f.truncate(1) # => -12345.6
f.truncate(3) # => -12345.678

f = 12345.6789
f.truncate(0)  # => 12345
f.truncate(-3) # => 12000

(0.3 / 0.1).truncate  #=> 2 (!)

#zero?

zero?true 또는 falseself0.0이면 true.