# <!-- rdoc-file=numeric.c -->
# A Float object represents a sometimes-inexact real number using the native
# architecture's double-precision floating point representation.
#
# Floating point has a different arithmetic and is an inexact number. So you
# should know its esoteric system. See following:
#
# *   https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
# *   https://github.com/rdp/ruby_tutorials_core/wiki/Ruby-Talk-FAQ#floats_impre
#     cise
# *   https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
#
#
# You can create a Float object explicitly with:
#
# *   A [floating-point
#     literal](doc/syntax/literals_rdoc.html#label-Float+Literals).
#
#
# You can convert certain objects to Floats with:
#
# *   Method [Float](Kernel.html#method-i-Float).
#
#
# ## What's Here
#
# First, what's elsewhere. Class Float:
#
# *   Inherits from [class
#     Numeric](Numeric.html#class-Numeric-label-What-27s+Here).
#
#
# Here, class Float provides methods for:
#
# *   [Querying](#class-Float-label-Querying)
# *   [Comparing](#class-Float-label-Comparing)
# *   [Converting](#class-Float-label-Converting)
#
#
# ### Querying
#
#     #finite?
# :       Returns whether `self` is finite.
#
#     #hash
# :       Returns the integer hash code for `self`.
#
#     #infinite?
# :       Returns whether `self` is infinite.
#
#     #nan?
# :       Returns whether `self` is a NaN (not-a-number).
#
#
#
# ### Comparing
#
#     [<](#method-i-3C)
# :       Returns whether `self` is less than the given value.
#
#     [<=](#method-i-3C-3D)
# :       Returns whether `self` is less than or equal to the given value.
#
#     [<=>](#method-i-3C-3D-3E)
# :       Returns a number indicating whether `self` is less than, equal to, or
#         greater than the given value.
#
#     [==](#method-i-3D-3D) (aliased as #=== and #eql>)
# :       Returns whether `self` is equal to the given value.
#
#     [>](#method-i-3E)
# :       Returns whether `self` is greater than the given value.
#
#     [>=](#method-i-3E-3D)
# :       Returns whether `self` is greater than or equal to the given value.
#
#
#
# ### Converting
#
#     #% (aliased as #modulo)
# :       Returns `self` modulo the given value.
#
#     #*
# :       Returns the product of `self` and the given value.
#
#     [**](#method-i-2A-2A)
# :       Returns the value of `self` raised to the power of the given value.
#
#     #+
# :       Returns the sum of `self` and the given value.
#
#     #-
# :       Returns the difference of `self` and the given value.
#
#     [/](#method-i-2F)
# :       Returns the quotient of `self` and the given value.
#
#     #ceil
# :       Returns the smallest number greater than or equal to `self`.
#
#     #coerce
# :       Returns a 2-element array containing the given value converted to a
#         Float and `self`
#
#     #divmod
# :       Returns a 2-element array containing the quotient and remainder
#         results of dividing `self` by the given value.
#
#     #fdiv
# :       Returns the Float result of dividing `self` by the given value.
#
#     #floor
# :       Returns the greatest number smaller than or equal to `self`.
#
#     #next_float
# :       Returns the next-larger representable Float.
#
#     #prev_float
# :       Returns the next-smaller representable Float.
#
#     #quo
# :       Returns the quotient from dividing `self` by the given value.
#
#     #round
# :       Returns `self` rounded to the nearest value, to a given precision.
#
#     #to_i (aliased as #to_int)
# :       Returns `self` truncated to an Integer.
#
#     #to_s (aliased as #inspect)
# :       Returns a string containing the place-value representation of `self`
#         in the given radix.
#
#     #truncate
# :       Returns `self` truncated to a given precision.
#
class Float < Numeric
  public

  # <!--
  #   rdoc-file=numeric.c
  #   - self % other -> float
  # -->
  # Returns `self` modulo `other` as a float.
  #
  # For float `f` and real number `r`, these expressions are equivalent:
  #
  #     f % r
  #     f-r*(f/r).floor
  #     f.divmod(r)[1]
  #
  # See Numeric#divmod.
  #
  # Examples:
  #
  #     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
  #
  # Float#modulo is an alias for Float#%.
  #
  def %: (Integer) -> Float
       | (Float) -> Float
       | (Rational) -> Float
       | (Numeric) -> Numeric

  # <!--
  #   rdoc-file=numeric.c
  #   - self * other -> numeric
  # -->
  # Returns a new Float which is the product of `self` and `other`:
  #
  #     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)
  #
  def *: (Complex) -> Complex
       | (Numeric) -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - self ** other -> numeric
  # -->
  # Raises `self` to the power of `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)
  #
  def **: (Complex) -> Complex
        | (Numeric) -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - self + other -> numeric
  # -->
  # Returns a new Float which is the sum of `self` and `other`:
  #
  #     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)
  #
  def +: (Complex) -> Complex
       | (Numeric) -> Float

  def +@: () -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - self - other -> numeric
  # -->
  # Returns a new Float which is the difference of `self` and `other`:
  #
  #     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)
  #
  def -: (Complex) -> Complex
       | (Numeric) -> Float

  # <!--
  #   rdoc-file=numeric.rb
  #   - -float  ->  float
  # -->
  # Returns `float`, negated.
  #
  def -@: () -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - self / other -> numeric
  # -->
  # Returns a new Float which is the result of dividing `self` by `other`:
  #
  #     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)
  #
  def /: (Complex) -> Complex
       | (Numeric) -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - self < other -> true or false
  # -->
  # Returns `true` if `self` is numerically less than `other`:
  #
  #     2.0 < 3              # => true
  #     2.0 < 3.0            # => true
  #     2.0 < Rational(3, 1) # => true
  #     2.0 < 2.0            # => false
  #
  # `Float::NAN < Float::NAN` returns an implementation-dependent value.
  #
  def <: (Numeric) -> bool

  # <!--
  #   rdoc-file=numeric.c
  #   - self <= other -> true or false
  # -->
  # Returns `true` if `self` is numerically less than or equal to `other`:
  #
  #     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
  #
  # `Float::NAN <= Float::NAN` returns an implementation-dependent value.
  #
  def <=: (Numeric) -> bool

  # <!--
  #   rdoc-file=numeric.c
  #   - self <=> other ->  -1, 0, +1, or nil
  # -->
  # Returns a value that depends on the numeric relation between `self` and
  # `other`:
  #
  # *   -1, if `self` is less than `other`.
  # *   0, if `self` is equal to `other`.
  # *   1, if `self` is greater than `other`.
  # *   `nil`, if the two values are incommensurate.
  #
  #
  # Examples:
  #
  #     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
  #
  # This is the basis for the tests in the Comparable module.
  #
  # `Float::NAN <=> Float::NAN` returns an implementation-dependent value.
  #
  def <=>: (Numeric) -> Integer?

  # <!--
  #   rdoc-file=numeric.c
  #   - self == other -> true or false
  # -->
  # Returns `true` if `other` has the same value as `self`, `false` otherwise:
  #
  #     2.0 == 2              # => true
  #     2.0 == 2.0            # => true
  #     2.0 == Rational(2, 1) # => true
  #     2.0 == Complex(2, 0)  # => true
  #
  # `Float::NAN == Float::NAN` returns an implementation-dependent value.
  #
  # Related: Float#eql? (requires `other` to be a Float).
  #
  def ==: (untyped) -> bool

  # <!-- rdoc-file=numeric.c -->
  # Returns `true` if `other` has the same value as `self`, `false` otherwise:
  #
  #     2.0 == 2              # => true
  #     2.0 == 2.0            # => true
  #     2.0 == Rational(2, 1) # => true
  #     2.0 == Complex(2, 0)  # => true
  #
  # `Float::NAN == Float::NAN` returns an implementation-dependent value.
  #
  # Related: Float#eql? (requires `other` to be a Float).
  #
  def ===: (untyped) -> bool

  # <!--
  #   rdoc-file=numeric.c
  #   - self > other -> true or false
  # -->
  # Returns `true` if `self` is numerically greater than `other`:
  #
  #     2.0 > 1              # => true
  #     2.0 > 1.0            # => true
  #     2.0 > Rational(1, 2) # => true
  #     2.0 > 2.0            # => false
  #
  # `Float::NAN > Float::NAN` returns an implementation-dependent value.
  #
  def >: (Numeric) -> bool

  # <!--
  #   rdoc-file=numeric.c
  #   - self >= other -> true or false
  # -->
  # Returns `true` if `self` is numerically greater than or equal to `other`:
  #
  #     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
  #
  # `Float::NAN >= Float::NAN` returns an implementation-dependent value.
  #
  def >=: (Numeric) -> bool

  # <!--
  #   rdoc-file=numeric.rb
  #   - float.abs        ->  float
  #   - float.magnitude  ->  float
  # -->
  # Returns the absolute value of `float`.
  #
  #     (-34.56).abs   #=> 34.56
  #     -34.56.abs     #=> 34.56
  #     34.56.abs      #=> 34.56
  #
  # Float#magnitude is an alias for Float#abs.
  #
  def abs: () -> Float

  def abs2: () -> Float

  # <!-- rdoc-file=complex.c -->
  # Returns 0 if the value is positive, pi otherwise.
  #
  def angle: () -> (Integer | Float)

  # <!--
  #   rdoc-file=complex.c
  #   - flo.arg    ->  0 or float
  #   - flo.angle  ->  0 or float
  #   - flo.phase  ->  0 or float
  # -->
  # Returns 0 if the value is positive, pi otherwise.
  #
  alias arg angle

  # <!--
  #   rdoc-file=numeric.c
  #   - ceil(ndigits = 0) -> float or integer
  # -->
  # Returns the smallest number greater than or equal to `self` with a precision
  # of `ndigits` decimal digits.
  #
  # When `ndigits` is positive, returns a float with `ndigits` digits after the
  # decimal point (as available):
  #
  #     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
  #
  # When `ndigits` is non-positive, returns an integer with at least `ndigits.abs`
  # trailing zeros:
  #
  #     f = 12345.6789
  #     f.ceil(0)  # => 12346
  #     f.ceil(-3) # => 13000
  #     f = -12345.6789
  #     f.ceil(0)  # => -12345
  #     f.ceil(-3) # => -12000
  #
  # Note that the limited precision of floating-point arithmetic may lead to
  # surprising results:
  #
  #     (2.1 / 0.7).ceil  #=> 4 (!)
  #
  # Related: Float#floor.
  #
  def ceil: () -> Integer
          | (int digits) -> (Integer | Float)

  # <!--
  #   rdoc-file=numeric.c
  #   - coerce(other) -> array
  # -->
  # Returns a 2-element array containing `other` converted to a Float and `self`:
  #
  #     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]
  #
  # Raises an exception if a type conversion fails.
  #
  def coerce: (Numeric) -> [ Float, Float ]

  def conj: () -> Float

  def conjugate: () -> Float

  # <!--
  #   rdoc-file=rational.c
  #   - flo.denominator  ->  integer
  # -->
  # Returns the denominator (always positive).  The result is machine dependent.
  #
  # See also Float#numerator.
  #
  def denominator: () -> Integer

  def div: (Numeric) -> Integer

  # <!--
  #   rdoc-file=numeric.c
  #   - divmod(other) -> array
  # -->
  # Returns a 2-element array `[q, r]`, where
  #
  #     q = (self/other).floor      # Quotient
  #     r = self % other            # Remainder
  #
  # Examples:
  #
  #     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]
  #     12.0.divmod(-4)             # => [-3, 0.0]
  #     -12.0.divmod(4)             # => [-3, -0.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]
  #
  def divmod: (Numeric) -> [ Numeric, Numeric ]

  def dup: () -> self

  # <!--
  #   rdoc-file=numeric.c
  #   - eql?(other) -> true or false
  # -->
  # Returns `true` if `other` is a Float with the same value as `self`, `false`
  # otherwise:
  #
  #     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::NAN.eql?(Float::NAN)` returns an implementation-dependent value.
  #
  # Related: Float#== (performs type conversions).
  #
  def eql?: (untyped) -> bool

  # <!-- rdoc-file=numeric.c -->
  # Returns the quotient from dividing `self` by `other`:
  #
  #     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)
  #
  # Float#fdiv is an alias for Float#quo.
  #
  def fdiv: (Complex) -> Complex
          | (Numeric) -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - finite? -> true or false
  # -->
  # Returns `true` if `self` is not `Infinity`, `-Infinity`, or `Nan`, `false`
  # otherwise:
  #
  #     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
  #
  def finite?: () -> bool

  # <!--
  #   rdoc-file=numeric.c
  #   - floor(ndigits = 0) -> float or integer
  # -->
  # Returns the largest number less than or equal to `self` with a precision of
  # `ndigits` decimal digits.
  #
  # When `ndigits` is positive, returns a float with `ndigits` digits after the
  # decimal point (as available):
  #
  #     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
  #
  # When `ndigits` is non-positive, returns an integer with at least `ndigits.abs`
  # trailing zeros:
  #
  #     f = 12345.6789
  #     f.floor(0)  # => 12345
  #     f.floor(-3) # => 12000
  #     f = -12345.6789
  #     f.floor(0)  # => -12346
  #     f.floor(-3) # => -13000
  #
  # Note that the limited precision of floating-point arithmetic may lead to
  # surprising results:
  #
  #     (0.3 / 0.1).floor  #=> 2 (!)
  #
  # Related: Float#ceil.
  #
  def floor: () -> Integer
           | (int digits) -> (Integer | Numeric)

  # <!--
  #   rdoc-file=numeric.c
  #   - hash -> integer
  # -->
  # Returns the integer hash value for `self`.
  #
  # See also Object#hash.
  #
  def hash: () -> Integer

  def i: () -> Complex

  def imag: () -> Integer

  def imaginary: () -> Integer

  # <!--
  #   rdoc-file=numeric.c
  #   - infinite? -> -1, 1, or nil
  # -->
  # Returns:
  #
  # *   1, if `self` is `Infinity`.
  # *   -1 if `self` is `-Infinity`.
  # *   `nil`, otherwise.
  #
  #
  # Examples:
  #
  #     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
  #
  def infinite?: () -> Integer?

  # <!-- rdoc-file=numeric.c -->
  # Returns a string containing a representation of `self`; depending of the value
  # of `self`, the string representation may contain:
  #
  # *   A fixed-point number.
  # *   A number in "scientific notation" (containing an exponent).
  # *   'Infinity'.
  # *   '-Infinity'.
  # *   'NaN' (indicating not-a-number).
  #
  #     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"
  #
  alias inspect to_s

  def integer?: () -> bool

  # <!--
  #   rdoc-file=numeric.rb
  #   - magnitude()
  # -->
  #
  alias magnitude abs

  # <!-- rdoc-file=numeric.c -->
  # Returns `self` modulo `other` as a float.
  #
  # For float `f` and real number `r`, these expressions are equivalent:
  #
  #     f % r
  #     f-r*(f/r).floor
  #     f.divmod(r)[1]
  #
  # See Numeric#divmod.
  #
  # Examples:
  #
  #     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
  #
  # Float#modulo is an alias for Float#%.
  #
  def modulo: (Numeric) -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - nan? -> true or false
  # -->
  # Returns `true` if `self` is a NaN, `false` otherwise.
  #
  #     f = -1.0     #=> -1.0
  #     f.nan?       #=> false
  #     f = 0.0/0.0  #=> NaN
  #     f.nan?       #=> true
  #
  def nan?: () -> bool

  # <!--
  #   rdoc-file=numeric.rb
  #   - float.negative?  ->  true or false
  # -->
  # Returns `true` if `float` is less than 0.
  #
  def negative?: () -> bool

  # <!--
  #   rdoc-file=numeric.c
  #   - next_float -> float
  # -->
  # Returns the next-larger representable Float.
  #
  # These examples show the internally stored values (64-bit hexadecimal) for each
  # Float `f` and for the corresponding `f.next_float`:
  #
  #     f = 0.0      # 0x0000000000000000
  #     f.next_float # 0x0000000000000001
  #
  #     f = 0.01     # 0x3f847ae147ae147b
  #     f.next_float # 0x3f847ae147ae147c
  #
  # In the remaining examples here, the output is shown in the usual way (result
  # `to_s`):
  #
  #     0.01.next_float    # => 0.010000000000000002
  #     1.0.next_float     # => 1.0000000000000002
  #     100.0.next_float   # => 100.00000000000001
  #
  #     f = 0.01
  #     (0..3).each_with_index {|i| printf "%2d %-20a %s\n", i, f, f.to_s; f = f.next_float }
  #
  # Output:
  #
  #      0 0x1.47ae147ae147bp-7 0.01
  #      1 0x1.47ae147ae147cp-7 0.010000000000000002
  #      2 0x1.47ae147ae147dp-7 0.010000000000000004
  #      3 0x1.47ae147ae147ep-7 0.010000000000000005
  #
  #     f = 0.0; 100.times { f += 0.1 }
  #     f                           # => 9.99999999999998       # should be 10.0 in the ideal world.
  #     10-f                        # => 1.9539925233402755e-14 # the floating point error.
  #     10.0.next_float-10          # => 1.7763568394002505e-15 # 1 ulp (unit in the last place).
  #     (10-f)/(10.0.next_float-10) # => 11.0                   # the error is 11 ulp.
  #     (10-f)/(10*Float::EPSILON)  # => 8.8                    # approximation of the above.
  #     "%a" % 10                   # => "0x1.4p+3"
  #     "%a" % f                    # => "0x1.3fffffffffff5p+3" # the last hex digit is 5.  16 - 5 = 11 ulp.
  #
  # Related: Float#prev_float
  #
  def next_float: () -> Float

  def nonzero?: () -> self?

  # <!--
  #   rdoc-file=rational.c
  #   - flo.numerator  ->  integer
  # -->
  # Returns the numerator.  The result is machine dependent.
  #
  #     n = 0.3.numerator    #=> 5404319552844595
  #     d = 0.3.denominator  #=> 18014398509481984
  #     n.fdiv(d)            #=> 0.3
  #
  # See also Float#denominator.
  #
  def numerator: () -> Integer

  # <!-- rdoc-file=complex.c -->
  # Returns 0 if the value is positive, pi otherwise.
  #
  alias phase angle

  def polar: () -> [ Float, Integer | Float ]

  # <!--
  #   rdoc-file=numeric.rb
  #   - float.positive?  ->  true or false
  # -->
  # Returns `true` if `float` is greater than 0.
  #
  def positive?: () -> bool

  # <!--
  #   rdoc-file=numeric.c
  #   - float.prev_float  ->  float
  # -->
  # Returns the next-smaller representable Float.
  #
  # These examples show the internally stored values (64-bit hexadecimal) for each
  # Float `f` and for the corresponding `f.pev_float`:
  #
  #     f = 5e-324   # 0x0000000000000001
  #     f.prev_float # 0x0000000000000000
  #
  #     f = 0.01     # 0x3f847ae147ae147b
  #     f.prev_float # 0x3f847ae147ae147a
  #
  # In the remaining examples here, the output is shown in the usual way (result
  # `to_s`):
  #
  #     0.01.prev_float   # => 0.009999999999999998
  #     1.0.prev_float    # => 0.9999999999999999
  #     100.0.prev_float  # => 99.99999999999999
  #
  #     f = 0.01
  #     (0..3).each_with_index {|i| printf "%2d %-20a %s\n", i, f, f.to_s; f = f.prev_float }
  #
  # Output:
  #
  #     0 0x1.47ae147ae147bp-7 0.01
  #     1 0x1.47ae147ae147ap-7 0.009999999999999998
  #     2 0x1.47ae147ae1479p-7 0.009999999999999997
  #     3 0x1.47ae147ae1478p-7 0.009999999999999995
  #
  # Related: Float#next_float.
  #
  def prev_float: () -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - quo(other) -> numeric
  # -->
  # Returns the quotient from dividing `self` by `other`:
  #
  #     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)
  #
  # Float#fdiv is an alias for Float#quo.
  #
  def quo: (Complex) -> Complex
         | (Numeric) -> Float

  # <!--
  #   rdoc-file=rational.c
  #   - flt.rationalize([eps])  ->  rational
  # -->
  # Returns a simpler approximation of the value (flt-|eps| <= result <=
  # flt+|eps|).  If the optional argument `eps` is not given, it will be chosen
  # automatically.
  #
  #     0.3.rationalize          #=> (3/10)
  #     1.333.rationalize        #=> (1333/1000)
  #     1.333.rationalize(0.01)  #=> (4/3)
  #
  # See also Float#to_r.
  #
  def rationalize: (?Numeric eps) -> Rational

  def real: () -> Float

  def real?: () -> true

  def rect: () -> [ Float, Numeric ]

  alias rectangular rect

  def remainder: (Numeric) -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - round(ndigits = 0, half: :up]) -> integer or float
  # -->
  # Returns `self` rounded to the nearest value with a precision of `ndigits`
  # decimal digits.
  #
  # When `ndigits` is non-negative, returns a float with `ndigits` after the
  # decimal point (as available):
  #
  #     f = 12345.6789
  #     f.round(1) # => 12345.7
  #     f.round(3) # => 12345.679
  #     f = -12345.6789
  #     f.round(1) # => -12345.7
  #     f.round(3) # => -12345.679
  #
  # When `ndigits` is negative, returns an integer with at least `ndigits.abs`
  # trailing zeros:
  #
  #     f = 12345.6789
  #     f.round(0)  # => 12346
  #     f.round(-3) # => 12000
  #     f = -12345.6789
  #     f.round(0)  # => -12346
  #     f.round(-3) # => -12000
  #
  # If keyword argument `half` is given, and `self` is equidistant from the two
  # candidate values, the rounding is according to the given `half` value:
  #
  # *   `:up` or `nil`: round away from zero:
  #
  #         2.5.round(half: :up)      # => 3
  #         3.5.round(half: :up)      # => 4
  #         (-2.5).round(half: :up)   # => -3
  #
  # *   `:down`: round toward zero:
  #
  #         2.5.round(half: :down)    # => 2
  #         3.5.round(half: :down)    # => 3
  #         (-2.5).round(half: :down) # => -2
  #
  # *   `:even`: round toward the candidate whose last nonzero digit is even:
  #
  #         2.5.round(half: :even)    # => 2
  #         3.5.round(half: :even)    # => 4
  #         (-2.5).round(half: :even) # => -2
  #
  #
  # Raises and exception if the value for `half` is invalid.
  #
  # Related: Float#truncate.
  #
  def round: (?half: :up | :down | :even) -> Integer
           | (int digits, ?half: :up | :down | :even) -> (Integer | Float)

  def step: (?Numeric limit, ?Numeric step) { (Float) -> void } -> self
          | (?Numeric limit, ?Numeric step) -> Enumerator[Float, self]
          | (?by: Numeric, ?to: Numeric) { (Float) -> void } -> self
          | (?by: Numeric, ?to: Numeric) -> Enumerator[Float, self]

  def to_c: () -> Complex

  # <!--
  #   rdoc-file=numeric.rb
  #   - float.to_f  ->  self
  # -->
  # Since `float` is already a Float, returns `self`.
  #
  def to_f: () -> Float

  # <!--
  #   rdoc-file=numeric.c
  #   - to_i -> integer
  # -->
  # Returns `self` truncated to an Integer.
  #
  #     1.2.to_i    # => 1
  #     (-1.2).to_i # => -1
  #
  # Note that the limited precision of floating-point arithmetic may lead to
  # surprising results:
  #
  #     (0.3 / 0.1).to_i  # => 2 (!)
  #
  # Float#to_int is an alias for Float#to_i.
  #
  def to_i: () -> Integer

  # <!-- rdoc-file=numeric.c -->
  # Returns `self` truncated to an Integer.
  #
  #     1.2.to_i    # => 1
  #     (-1.2).to_i # => -1
  #
  # Note that the limited precision of floating-point arithmetic may lead to
  # surprising results:
  #
  #     (0.3 / 0.1).to_i  # => 2 (!)
  #
  # Float#to_int is an alias for Float#to_i.
  #
  alias to_int to_i

  # <!--
  #   rdoc-file=rational.c
  #   - flt.to_r  ->  rational
  # -->
  # Returns the value as a 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)
  #
  # NOTE: 0.3.to_r isn't the same as "0.3".to_r.  The latter is equivalent to
  # "3/10".to_r, but the former isn't so.
  #
  #     0.3.to_r   == 3/10r  #=> false
  #     "0.3".to_r == 3/10r  #=> true
  #
  # See also Float#rationalize.
  #
  def to_r: () -> Rational

  # <!--
  #   rdoc-file=numeric.c
  #   - to_s -> string
  # -->
  # Returns a string containing a representation of `self`; depending of the value
  # of `self`, the string representation may contain:
  #
  # *   A fixed-point number.
  # *   A number in "scientific notation" (containing an exponent).
  # *   'Infinity'.
  # *   '-Infinity'.
  # *   'NaN' (indicating not-a-number).
  #
  #     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"
  #
  def to_s: () -> String

  # <!--
  #   rdoc-file=numeric.c
  #   - truncate(ndigits = 0) -> float or integer
  # -->
  # Returns `self` truncated (toward zero) to a precision of `ndigits` decimal
  # digits.
  #
  # When `ndigits` is positive, returns a float with `ndigits` digits after the
  # decimal point (as available):
  #
  #     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
  #
  # When `ndigits` is negative, returns an integer with at least `ndigits.abs`
  # trailing zeros:
  #
  #     f = 12345.6789
  #     f.truncate(0)  # => 12345
  #     f.truncate(-3) # => 12000
  #     f = -12345.6789
  #     f.truncate(0)  # => -12345
  #     f.truncate(-3) # => -12000
  #
  # Note that the limited precision of floating-point arithmetic may lead to
  # surprising results:
  #
  #     (0.3 / 0.1).truncate  #=> 2 (!)
  #
  # Related: Float#round.
  #
  def truncate: () -> Integer
              | (Integer ndigits) -> (Integer | Float)

  # <!--
  #   rdoc-file=numeric.rb
  #   - float.zero?  ->  true or false
  # -->
  # Returns `true` if `float` is 0.0.
  #
  def zero?: () -> bool
end

# <!-- rdoc-file=numeric.c -->
# The minimum number of significant decimal digits in a double-precision
# floating point.
#
# Usually defaults to 15.
#
Float::DIG: Integer

# <!-- rdoc-file=numeric.c -->
# The difference between 1 and the smallest double-precision floating point
# number greater than 1.
#
# Usually defaults to 2.2204460492503131e-16.
#
Float::EPSILON: Float

# <!-- rdoc-file=numeric.c -->
# An expression representing positive infinity.
#
Float::INFINITY: Float

Float::Infinity: Float

# <!-- rdoc-file=numeric.c -->
# The number of base digits for the `double` data type.
#
# Usually defaults to 53.
#
Float::MANT_DIG: Integer

# <!-- rdoc-file=numeric.c -->
# The largest possible integer in a double-precision floating point number.
#
# Usually defaults to 1.7976931348623157e+308.
#
Float::MAX: Float

# <!-- rdoc-file=numeric.c -->
# The largest positive exponent in a double-precision floating point where 10
# raised to this power minus 1.
#
# Usually defaults to 308.
#
Float::MAX_10_EXP: Integer

# <!-- rdoc-file=numeric.c -->
# The largest possible exponent value in a double-precision floating point.
#
# Usually defaults to 1024.
#
Float::MAX_EXP: Integer

# <!-- rdoc-file=numeric.c -->
# The smallest positive normalized number in a double-precision floating point.
#
# Usually defaults to 2.2250738585072014e-308.
#
# If the platform supports denormalized numbers, there are numbers between zero
# and Float::MIN. 0.0.next_float returns the smallest positive floating point
# number including denormalized numbers.
#
Float::MIN: Float

# <!-- rdoc-file=numeric.c -->
# The smallest negative exponent in a double-precision floating point where 10
# raised to this power minus 1.
#
# Usually defaults to -307.
#
Float::MIN_10_EXP: Integer

# <!-- rdoc-file=numeric.c -->
# The smallest possible exponent value in a double-precision floating point.
#
# Usually defaults to -1021.
#
Float::MIN_EXP: Integer

# <!-- rdoc-file=numeric.c -->
# An expression representing a value which is "not a number".
#
Float::NAN: Float

# <!-- rdoc-file=numeric.c -->
# The base of the floating point, or number of unique digits used to represent
# the number.
#
# Usually defaults to 2 on most systems, which would represent a base-10
# decimal.
#
Float::RADIX: Integer

# Deprecated, do not use.
#
# Represents the rounding mode for floating point addition at the start time.
#
# Usually defaults to 1, rounding to the nearest number.
#
# Other modes include:
#
# -1
# :   Indeterminable
# 0
# :   Rounding towards zero
# 1
# :   Rounding to the nearest number
# 2
# :   Rounding towards positive infinity
# 3
# :   Rounding towards negative infinity
#
#
Float::ROUNDS: Integer
