Float 클래스

Float 클래스 (Float)

Float 객체는 네이티브 아키텍처의 double-precision 부동소수점 표현을 사용해서 실수를 저장해요.

출처: Ruby 4.0 API

본문

Float의 부정확성 (Float Imprecisions)

어떤 실수는 Float 객체로 정확히 표현돼요.

37.5    # => 37.5
98.75   # => 98.75
12.3125 # => 12.3125

하지만 초월수(transcendental number)들처럼 정확히 표현되지 못하는 것들도 있어요. 수학에서 무한 정밀도의 π는 Ruby에서 유한 정밀도(여기서는 소수 16자리)예요.

Math::PI # => 3.141592653589793
Math::E  # => 2.718281828459045

단순한 계산조차 부정확성을 가져올 수 있어요.

x = 0.1 + 0.2 # => 0.30000000000000004
y = 0.3       # => 0.3
x == y        # => false

유리수의 정확한 저장과 계산은 Rational 객체로 가능해요.

Float 만들기 (Creating a Float)

부동소수점 리터럴로 만들거나, Float 메서드로 특정 객체를 변환해 만들 수 있어요.

Float가 제공하는 것 (What's Here)

FloatNumericObject에서 상속하고 Comparable을 포함해요. 자체적으로 조회(Querying), 비교(Comparing), 변환(Converting) 메서드를 제공해요.

  • Querying: finite?, hash, infinite?, nan?
  • 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 / MAX_EXP — 가장 큰 양의 지수(보통 308 / 1024).
  • MIN — 가장 작은 양의 정규화 수. 보통 2.2250738582014014e-308(문서값 2.2250738585072014e-308). 플랫폼이 denormalized 수를 지원하면 0과 Float::MIN 사이에도 수가 있어요. 0.0.next_float가 denormalized 수를 포함한 가장 작은 양의 부동소수점 수를 돌려줘요.
  • MIN_10_EXP / MIN_EXP — 가장 작은 음의 지수(보통 -307 / -1021).
  • NAN — "숫자가 아님"을 나타내는 값.
  • RADIX — 부동소수점의 base. 대부분의 시스템에서 2.

#% (Public Instance Method)

self % other → float (별칭 modulo) — selfother로 나눈 나머지를 Float로 돌려줘요. f % rf-r*(f/r).floor와 동등해요.

10.0 % 2              # => 0.0
10.0 % 3              # => 1.0
10.0 % -3             # => -2.0
10.0 % Rational(4, 1) # => 2.0

#* / #** / #+ / #- (Public Instance Method)

self * other → numeric — 곱. self ** exponent → numeric — 거듭제곱. self + other → float 또는 complex — 합. self - other → numeric — 차. -self → float — 부호 반전.

f = 3.14
f * 2              # => 6.28
f ** 2             # => 9.8596
f + 1              # => 4.140000000000001
f - 1              # => 2.14
-3.14              # => -3.14

#/ (Public Instance Method)

self / other → numeric — 몫.

f = 3.14
f / 2              # => 1.57
f / Rational(2, 1) # => 1.57

#< / #<= / #<=> / #== / #> / #>= (Public Instance Method)

비교 연산자들이에요. other는 numeric이어야 하고 Complex는 안 돼요.

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

<=>-1(self가 작음), 0(같음), 1(self가 큼), nil(비교 불가)을 돌려줘요. ==(별칭 ===)는 값이 같으면 true. Float::NAN 관련 비교는 구현에 따라 달라요. FloatComparable을 포함하므로 그 메서드들도 <=>를 사용해요.

#abs (Public Instance Method)

abs → float (별칭 magnitude) — 절댓값.

(-34.56).abs # => 34.56

#arg (Public Instance Method)

arg → 0 또는 Math::PI (별칭 angle, phase) — self가 양수면 0, 아니면 Math::PI.

#ceil / #floor / #truncate (Public Instance Method)

ceil(ndigits = 0) → float 또는 integer — self의 "올림" 값. floor(ndigits = 0) → float 또는 integer — "내림" 값. truncate(ndigits = 0) → float 또는 integer — 0을 향한 절삭 값.

ndigits가 양수면 소수점 이하 ndigits 자리(최소 1)를 가진 Float을, 0 이하면 계산된 세분화 단위(granularity)에 기반한 Integer를 돌려줘요. ndigits가 0보다 작으면 10 ** ndigits.abs 단위의 배수 중 self보다 작거나 같은 가장 큰 값(floor/truncate) 또는 크거나 같은 가장 작은 값(ceil)을 돌려줘요.

f = 12345.6789
f.ceil(1)   # => 12345.7
f.ceil(-1)  # => 12350
f.floor(1)  # => 12345.6
f.floor(-1) # => 12340
f.truncate(1)  # => 12345.6
f.truncate(-3) # => 12000

부동소수점 연산의 제한 때문에 의외의 결과가 나올 수 있어요.

(2.1 / 0.7).ceil  #=> 4 # Not 3
(0.3 / 0.1).floor # => 2 # Not 3

#coerce (Public Instance Method)

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

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

#denominator / #numerator (Public Instance Method)

denominator → integer — 분모(항상 양수). numerator → integer — 분자. 둘 다 머신 의존적이에요.

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

#divmod (Public Instance Method)

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

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

#eql? (Public Instance Method)

eql?(other) → true 또는 false — otherself와 같은 값을 가진 Float이면 true. ==와 달리 타입 변환을 하지 않아요.

2.0.eql?(2.0)            # => true
2.0.eql?(1)              # => false

#finite? / #infinite? / #nan? (Public Instance Method)

finite? → true 또는 false — Infinity, -Infinity, NaN이 아니면 true. infinite? → -1, 1, 또는 nil — Infinity면 1, -Infinity면 -1, 그 외 nil. nan? → true 또는 false — NaN이면 true.

f = 1.0/0.0  # => Infinity
f.finite?    # => false
f.infinite?  # => 1
f = 0.0/0.0  # => NaN
f.nan?       # => true

#hash (Public Instance Method)

hash → integer — self의 정수 해시 값을 돌려줘요.

#negative? / #positive? / #zero? (Public Instance Method)

negative? → true 또는 false — 0보다 작으면 true. positive? → true 또는 false — 0보다 크면 true. zero? → true 또는 false — 0.0이면 true.

#next_float / #prev_float (Public Instance Method)

next_float → float — 표현 가능한 다음으로 큰 Float. prev_float → float — 표현 가능한 다음으로 작은 Float.

0.01.next_float  # => 0.010000000000000002
0.01.prev_float  # => 0.009999999999999998

#quo (Public Instance Method)

quo(other) → numeric (별칭 fdiv) — selfother로 나눈 몫.

f = 3.14
f.quo(2)              # => 1.57
f.quo(Rational(2, 1)) # => 1.57

#rationalize (Public Instance Method)

rationalize([eps]) → rational — 값의 더 단순한 근사(flt-|eps| <= result <= flt+|eps|)를 돌려줘요. eps를 주지 않으면 자동 선택돼요. Float#to_r 참고.

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

#round (Public Instance Method)

round(ndigits = 0, half: :up) → integer 또는 float — ndigits 소수 자릿수의 정밀도로 가장 가까운 값에 반올림해요. half 키워드는 두 후보 값에 정확히 중간일 때의 반올림 방식을 정해요 — :up(0에서 멀어짐, 기본), :down(0으로), :even(마지막 0이 아닌 자리가 짝수인 쪽).

f = 12345.6789
f.round(1)  # => 12345.7
f.round(-3) # => 12000
2.5.round(half: :up)      # => 3
2.5.round(half: :down)    # => 2
2.5.round(half: :even)    # => 2

#to_f / #to_i / #to_int (Public Instance Method)

to_f → self — 이미 Float이라 그대로 돌려줘요. to_i → integer (별칭 to_int) — Integer로 절삭한 값.

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

#to_r (Public Instance Method)

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

2.0.to_r   #=> (2/1)
2.5.to_r   #=> (5/2)
0.3.to_r   #=> (5404319552844595/18014398509481984)

0.3.to_r"0.3".to_r과 같지 않아요. 전자는 실제 부동소수점 값을 기반으로 하기 때문이죠.

#to_s / #inspect (Public Instance Method)

to_s → string — self의 표현을 담은 문자열. 값에 따라 고정소수점("3.14"), 과학적 표기("1.644631821843879e+50"), "Infinity", "-Infinity", "NaN" 중 하나를 돌려줘요.