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메서드로 특정 객체를 변환
Float는 Numeric 클래스에서 상속받아요. 여기서는 Float가 직접 제공하는 메서드들을 살펴볼게요: 질의(querying), 비교(comparing), 변환(converting).
출처: Ruby 3.3 API
본문
Querying (질의)
finite?—self가 유한한지hash—self의 정수 해시 코드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) 수를 지원하면0과Float::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 — self를 other로 나눈 나머지를 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 — self와 other의 곱인 새 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 — self를 other의 거듭제곱으로 올려요.
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 — self와 other의 합인 새 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 — self와 other의 차인 새 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 — self를 other로 나눈 결과인 새 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 < other → true 또는 false — self가 수치적으로 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 <= other → true 또는 false — self가 수치적으로 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 — self와 other의 수치 관계에 따라 값을 돌려줘요.
- -1:
self가other보다 작을 때 - 0:
self가other와 같을 때 - 1:
self가other보다 클 때 - 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 == other → true 또는 false — other가 self와 같은 값이면 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?(other가 Float여야 함). ===의 별칭이에요.
#> (Public Instance Method)
self > other → true 또는 false — self가 수치적으로 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 >= other → true 또는 false — self가 수치적으로 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::PI — self가 양수면 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 — other를 Float로 변환한 값과 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 또는 false — other가 self와 같은 값을 가진 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
fdiv — quo의 별칭이에요.
#finite? (Public Instance Method)
finite? → true 또는 false — self가 Infinity, -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 — self가 Infinity면 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 또는 false — self가 NaN이면 true.
f = -1.0 #=> -1.0
f.nan? #=> false
f = 0.0/0.0 #=> NaN
f.nan? #=> true
#negative?
negative? → true 또는 false — self가 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 또는 false — self가 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 — self를 other로 나눈 몫을 돌려줘요. 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 — self를 ndigits 십진 자릿수 정밀도의 가장 가까운 값으로 반올림해요. 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 — self를 Integer로 잘라낸(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 또는 false — self가 0.0이면 true.