diff --git a/core/float.rbs b/core/float.rbs
index d5d00a50a..a6e0acfcb 100644
--- a/core/float.rbs
+++ b/core/float.rbs
@@ -253,6 +253,122 @@
# * #truncate: Returns `self` truncated to a given precision.
#
class Float < Numeric
+ #
+ # The minimum number of significant decimal digits in a double-precision
+ # floating point.
+ #
+ # Usually defaults to 15.
+ #
+ DIG: Integer
+
+ #
+ # The difference between 1 and the smallest double-precision floating point
+ # number greater than 1.
+ #
+ # Usually defaults to 2.2204460492503131e-16.
+ #
+ EPSILON: Float
+
+ #
+ # An expression representing positive infinity.
+ #
+ INFINITY: Float
+
+ %a{deprecated:Does not actually exist}
+ Infinity: Float
+
+ #
+ # The number of base digits for the `double` data type.
+ #
+ # Usually defaults to 53.
+ #
+ MANT_DIG: Integer
+
+ #
+ # The largest possible integer in a double-precision floating point number.
+ #
+ # Usually defaults to 1.7976931348623157e+308.
+ #
+ MAX: Float
+
+ #
+ # The largest positive exponent in a double-precision floating point where 10
+ # raised to this power minus 1.
+ #
+ # Usually defaults to 308.
+ #
+ MAX_10_EXP: Integer
+
+ #
+ # The largest possible exponent value in a double-precision floating point.
+ #
+ # Usually defaults to 1024.
+ #
+ MAX_EXP: Integer
+
+ #
+ # 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.
+ #
+ MIN: Float
+
+ #
+ # The smallest negative exponent in a double-precision floating point where 10
+ # raised to this power minus 1.
+ #
+ # Usually defaults to -307.
+ #
+ MIN_10_EXP: Integer
+
+ #
+ # The smallest possible exponent value in a double-precision floating point.
+ #
+ # Usually defaults to -1021.
+ #
+ MIN_EXP: Integer
+
+ #
+ # An expression representing a value which is "not a number".
+ #
+ NAN: Float
+
+ #
+ # 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.
+ #
+ 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
+ #
+ #
+ %a{deprecated}
+ ROUNDS: Integer
+
#
# Returns `true` if `other` has the same value as `self`, `false` otherwise:
@@ -475,7 +593,7 @@ class Float < Numeric
#
# Related: Float#eql? (requires `other` to be a Float).
#
- def ===: (untyped) -> bool
+ alias === ==
#
# Returns 0 if `self` is positive, Math::PI otherwise.
#
- def angle: ...
+ alias angle arg
#
# Returns 0 if `self` is positive, Math::PI otherwise.
#
- alias arg angle
+ def arg: () -> (0 | Float) # NB: Can also return `NaN` if self is NaN
#
# Returns the quotient from dividing `self` by `other`:
@@ -679,8 +804,7 @@ class Float < Numeric
# f.quo(Rational(2, 1)) # => 1.57
# f.quo(Complex(2, 0)) # => (1.57+0.0i)
#
- def fdiv: (Complex) -> Complex
- | (Numeric) -> Float
+ alias fdiv quo
#
# Returns a string containing a representation of `self`; depending of the value
@@ -848,7 +972,7 @@ class Float < Numeric
# 10.0 % 4.0 # => 2.0
# 10.0 % Rational(4, 1) # => 2.0
#
- def modulo: (Numeric) -> Float
+ alias modulo %
#
# Returns 0 if `self` is positive, Math::PI otherwise.
#
- alias phase angle
+ alias phase arg
def polar: () -> [ Float, Integer | Float ]
@@ -993,8 +1117,8 @@ class Float < Numeric
# f.quo(Rational(2, 1)) # => 1.57
# f.quo(Complex(2, 0)) # => (1.57+0.0i)
#
- def quo: (Complex) -> Complex
- | (Numeric) -> Float
+ def quo: (Integer | Float other) -> Float
+ | [S, R] (Numeric::_Coerce[self, RBS::Ops::_Divide[S, R], S] other) -> R
#
# Returns `self` (which is already a Float).
#
- def to_f: () -> Float
+ def to_f: () -> self
#
-# The minimum number of significant decimal digits in a double-precision
-# floating point.
-#
-# Usually defaults to 15.
-#
-Float::DIG: Integer
-
-#
-# The difference between 1 and the smallest double-precision floating point
-# number greater than 1.
-#
-# Usually defaults to 2.2204460492503131e-16.
-#
-Float::EPSILON: Float
-
-#
-# An expression representing positive infinity.
-#
-Float::INFINITY: Float
-
-Float::Infinity: Float
-
-#
-# The number of base digits for the `double` data type.
-#
-# Usually defaults to 53.
-#
-Float::MANT_DIG: Integer
-
-#
-# The largest possible integer in a double-precision floating point number.
-#
-# Usually defaults to 1.7976931348623157e+308.
-#
-Float::MAX: Float
-
-#
-# 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
-
-#
-# The largest possible exponent value in a double-precision floating point.
-#
-# Usually defaults to 1024.
-#
-Float::MAX_EXP: Integer
-
-#
-# 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
-
-#
-# 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
-
-#
-# The smallest possible exponent value in a double-precision floating point.
-#
-# Usually defaults to -1021.
-#
-Float::MIN_EXP: Integer
-
-#
-# An expression representing a value which is "not a number".
-#
-Float::NAN: Float
-
-#
-# 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
diff --git a/core/numeric.rbs b/core/numeric.rbs
index fe6f800cd..cfa450c0b 100644
--- a/core/numeric.rbs
+++ b/core/numeric.rbs
@@ -158,6 +158,14 @@
class Numeric
include Comparable
+ # The direction you can round
+ type round_mode = :up | :down | :even | 'up' | 'down' | 'even' | string | nil
+
+ # An interface that indicates a type can be coerced.
+ interface _Coerce[O, Other, Self]
+ def coerce: (O other) -> [Other, Self]
+ end
+
#