//===--- FloatingPoint.swift.gyb ------------------------------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

%{

from SwiftIntTypes import all_integer_types

# Number of bits in the Builtin.Word type
word_bits = int(CMAKE_SIZEOF_VOID_P) * 8

}%

/// A floating-point numeric type.
///
/// Floating-point types are used to represent fractional numbers, like 5.5,
/// 100.0, or 3.14159274. Each floating-point type has its own possible range
/// and precision. The floating-point types in the standard library are
/// `Float`, `Double`, and `Float80` where available.
///
/// Create new instances of floating-point types using integer or
/// floating-point literals. For example:
///
///     let temperature = 33.2
///     let recordHigh = 37.5
///
/// The `FloatingPoint` protocol declares common arithmetic operations, so you
/// can write functions and algorithms that work on any floating-point type.
/// The following example declares a function that calculates the length of
/// the hypotenuse of a right triangle given its two perpendicular sides.
/// Because the `hypotenuse(_:_:)` function uses a generic parameter
/// constrained to the `FloatingPoint` protocol, you can call it using any
/// floating-point type.
///
///     func hypotenuse<T: FloatingPoint>(_ a: T, _ b: T) -> T {
///         return (a * a + b * b).squareRoot()
///     }
///
///     let (dx, dy) = (3.0, 4.0)
///     let distance = hypotenuse(dx, dy)
///     // distance == 5.0
///
/// Floating-point values are represented as a *sign* and a *magnitude*, where
/// the magnitude is calculated using the type's *radix* and the instance's
/// *significand* and *exponent*. This magnitude calculation takes the
/// following form for a floating-point value `x` of type `F`, where `**` is
/// exponentiation:
///
///     x.significand * F.radix ** x.exponent
///
/// Here's an example of the number -8.5 represented as an instance of the
/// `Double` type, which defines a radix of 2.
///
///     let y = -8.5
///     // y.sign == .minus
///     // y.significand == 1.0625
///     // y.exponent == 3
///
///     let magnitude = 1.0625 * Double(2 ** 3)
///     // magnitude == 8.5
///
/// Types that conform to the `FloatingPoint` protocol provide most basic
/// (clause 5) operations of the [IEEE 754 specification][spec]. The base,
/// precision, and exponent range are not fixed in any way by this protocol,
/// but it enforces the basic requirements of any IEEE 754 floating-point
/// type.
///
/// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
///
/// Additional Considerations
/// =========================
///
/// In addition to representing specific numbers, floating-point types also
/// have special values for working with overflow and nonnumeric results of
/// calculation.
///
/// Infinity
/// --------
///
/// Any value whose magnitude is so great that it would round to a value
/// outside the range of representable numbers is rounded to *infinity*. For a
/// type `F`, positive and negative infinity are represented as `F.infinity`
/// and `-F.infinity`, respectively. Positive infinity compares greater than
/// every finite value and negative infinity, while negative infinity compares
/// less than every finite value and positive infinity. Infinite values with
/// the same sign are equal to each other.
///
///     let values: [Double] = [10.0, 25.0, -10.0, .infinity, -.infinity]
///     print(values.sorted())
///     // Prints "[-inf, -10.0, 10.0, 25.0, inf]"
///
/// Operations with infinite values follow real arithmetic as much as possible:
/// Adding or subtracting a finite value, or multiplying or dividing infinity
/// by a nonzero finite value, results in infinity.
///
/// NaN ("not a number")
/// --------------------
///
/// Floating-point types represent values that are neither finite numbers nor
/// infinity as NaN, an abbreviation for "not a number." Comparing a NaN with
/// any value, including another NaN, results in `false`.
///
///     let myNaN = Double.nan
///     print(myNaN > 0)
///     // Prints "false"
///     print(myNaN < 0)
///     // Prints "false"
///     print(myNaN == .nan)
///     // Prints "false"
///
/// Because testing whether one NaN is equal to another NaN results in `false`,
/// use the `isNaN` property to test whether a value is NaN.
///
///     print(myNaN.isNaN)
///     // Prints "true"
///
/// NaN propagates through many arithmetic operations. When you are operating
/// on many values, this behavior is valuable because operations on NaN simply
/// forward the value and don't cause runtime errors. The following example
/// shows how NaN values operate in different contexts.
///
/// Imagine you have a set of temperature data for which you need to report
/// some general statistics: the total number of observations, the number of
/// valid observations, and the average temperature. First, a set of
/// observations in Celsius is parsed from strings to `Double` values:
///
///     let temperatureData = ["21.5", "19.25", "27", "no data", "28.25", "no data", "23"]
///     let tempsCelsius = temperatureData.map { Double($0) ?? .nan }
///     // tempsCelsius == [21.5, 19.25, 27, nan, 28.25, nan, 23.0]
///
/// Note that some elements in the `temperatureData ` array are not valid
/// numbers. When these invalid strings are parsed by the `Double` failable
/// initializer, the example uses the nil-coalescing operator (`??`) to
/// provide NaN as a fallback value.
///
/// Next, the observations in Celsius are converted to Fahrenheit:
///
///     let tempsFahrenheit = tempsCelsius.map { $0 * 1.8 + 32 }
///     // tempsFahrenheit == [70.7, 66.65, 80.6, nan, 82.85, nan, 73.4]
///
/// The NaN values in the `tempsCelsius` array are propagated through the
/// conversion and remain NaN in `tempsFahrenheit`.
///
/// Because calculating the average of the observations involves combining
/// every value of the `tempsFahrenheit` array, any NaN values cause the
/// result to also be NaN, as seen in this example:
///
///     let badAverage = tempsFahrenheit.reduce(0.0, combine: +) / Double(tempsFahrenheit.count)
///     // badAverage.isNaN == true
///
/// Instead, when you need an operation to have a specific numeric result,
/// filter out any NaN values using the `isNaN` property.
///
///     let validTemps = tempsFahrenheit.filter { !$0.isNaN }
///     let average = validTemps.reduce(0.0, combine: +) / Double(validTemps.count)
///
/// Finally, report the average temperature and observation counts:
///
///     print("Average: \(average)°F in \(validTemps.count) " +
///           "out of \(tempsFahrenheit.count) observations.")
///     // Prints "Average: 74.84°F in 5 out of 7 observations."
public protocol FloatingPoint: Comparable, Arithmetic,
  SignedNumber, Strideable, Hashable {

  /// A type that represents any written exponent.
  associatedtype Exponent: SignedInteger

  /// Creates a new value from the given sign, exponent, and significand.
  ///
  /// The following example uses this initializer to create a new `Double`
  /// instance. `Double` is a binary floating-point type that has a radix of
  /// `2`.
  ///
  ///     let x = Double(sign: .plus, exponent: -2, significand: 1.5)
  ///     // x == 0.375
  ///
  /// This initializer is equivalent to the following calculation, where `**`
  /// is exponentiation, computed as if by a single, correctly rounded,
  /// floating-point operation:
  ///
  ///     let sign: FloatingPointSign = .plus
  ///     let exponent = -2
  ///     let significand = 1.5
  ///     let y = (sign == .minus ? -1 : 1) * significand * Double.radix ** exponent
  ///     // y == 0.375
  ///
  /// As with any basic operation, if this value is outside the representable
  /// range of the type, overflow or underflow occurs, and zero, a subnormal
  /// value, or infinity may result. In addition, there are two other edge
  /// cases:
  ///
  /// - If the value you pass to `significand` is zero or infinite, the result
  ///   is zero or infinite, regardless of the value of `exponent`.
  /// - If the value you pass to `significand` is NaN, the result is NaN.
  ///
  /// For any floating-point value `x` of type `F`, the result of the following
  /// is equal to `x`, with the distinction that the result is canonicalized
  /// if `x` is in a noncanonical encoding:
  ///
  ///     let x0 = F(sign: x.sign, exponent: x.exponent, significand: x.significand)
  ///
  /// This initializer implements the `scaleB` operation defined by the [IEEE
  /// 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameters:
  ///   - sign: The sign to use for the new value.
  ///   - exponent: The new value's exponent.
  ///   - significand: The new value's significand.
  init(sign: FloatingPointSign, exponent: Exponent, significand: Self)

  /// Creates a new floating-point value using the sign of one value and the
  /// magnitude of another.
  ///
  /// The following example uses this initializer to create a new `Double`
  /// instance with the sign of `a` and the magnitude of `b`:
  ///
  ///     let a = -21.5
  ///     let b = 305.15
  ///     let c = Double(signOf: a, magnitudeOf: b)
  ///     print(c)
  ///     // Prints "-305.15"
  ///
  /// This initializer implements the IEEE 754 `copysign` operation.
  ///
  /// - Parameters:
  ///   - signOf: A value from which to use the sign. The result of the
  ///     initializer has the same sign as `signOf`.
  ///   - magnitudeOf: A value from which to use the magnitude. The result of
  ///     the initializer has the same magnitude as `magnitudeOf`.
  init(signOf: Self, magnitudeOf: Self)

% for src_ty in all_integer_types(word_bits):
  /// Creates a new value, rounded to the closest possible representation.
  ///
  /// If two representable values are equally close, the result is the value
  /// with more trailing zeros in its significand bit pattern.
  ///
  /// - Parameter value: The integer to convert to a floating-point value.
  init(_ value: ${src_ty.stdlib_name})

% end
  /*  TODO: Implement the following APIs once a revised integer protocol is
      introduced that allows for them to be implemented. In particular, we
      need to have an "index of most significant bit" operation and "get
      absolute value as unsigned type" operation on the Integer protocol.

  /// Creates the closest representable value to the given integer.
  ///
  /// - Parameter value: The integer to represent as a floating-point value.
  init<Source: Integer>(_ value: Source)

  /// Creates a value that exactly represents the given integer.
  ///
  /// If the given integer is outside the representable range of the type, the
  /// result is `nil`.
  ///
  /// - Parameter value: The integer to represent as a floating-point value.
  init?<Source: Integer>(exactly value: Source)
  */

  /// The radix, or base of exponentiation, for a floating-point type.
  ///
  /// The magnitude of a floating-point value `x` of type `F` can be calculated
  /// by using the following formula, where `**` is exponentiation:
  ///
  ///     let magnitude = x.significand * F.radix ** x.exponent
  ///
  /// A conforming type may use any integer radix, but values other than 2 (for
  /// binary floating-point types) or 10 (for decimal floating-point types)
  /// are extraordinarily rare in practice.
  static var radix: Int { get }

  /// A quiet NaN ("not a number").
  ///
  /// A NaN compares not equal, not greater than, and not less than every
  /// value, including itself. Passing a NaN to an operation generally results
  /// in NaN.
  ///
  ///     let x = 1.21
  ///     // x > Double.nan == false
  ///     // x < Double.nan == false
  ///     // x == Double.nan == false
  ///
  /// Because a NaN always compares not equal to itself, to test whether a
  /// floating-point value is NaN, use its `isNaN` property instead of the
  /// equal-to operator (`==`). In the following example, `y` is NaN.
  ///
  ///     let y = x + Double.nan
  ///     print(y == Double.nan)
  ///     // Prints "false"
  ///     print(y.isNaN)
  ///     // Prints "true"
  ///
  /// - SeeAlso: `isNaN`, `signalingNaN`
  static var nan: Self { get }

  /// A signaling NaN ("not a number").
  ///
  /// The default IEEE 754 behavior of operations involving a signaling NaN is
  /// to raise the Invalid flag in the floating-point environment and return a
  /// quiet NaN.
  ///
  /// Operations on types conforming to the `FloatingPoint` protocol should
  /// support this behavior, but they might also support other options. For
  /// example, it would be reasonable to implement alternative operations in
  /// which operating on a signaling NaN triggers a runtime error or results
  /// in a diagnostic for debugging purposes. Types that implement alternative
  /// behaviors for a signaling NaN must document the departure.
  ///
  /// Other than these signaling operations, a signaling NaN behaves in the
  /// same manner as a quiet NaN.
  ///
  /// - SeeAlso: `nan`
  static var signalingNaN: Self { get }

  /// Positive infinity.
  ///
  /// Infinity compares greater than all finite numbers and equal to other
  /// infinite values.
  ///
  ///     let x = Double.greatestFiniteMagnitude
  ///     let y = x * 2
  ///     // y == Double.infinity
  ///     // y > x
  static var infinity: Self { get }

  /// The greatest finite number representable by this type.
  ///
  /// This value compares greater than or equal to all finite numbers, but less
  /// than `infinity`.
  ///
  /// This value corresponds to type-specific C macros such as `FLT_MAX` and
  /// `DBL_MAX`. The naming of those macros is slightly misleading, because
  /// `infinity` is greater than this value.
  static var greatestFiniteMagnitude: Self { get }

  /// The mathematical constant pi.
  ///
  /// This value should be rounded toward zero to keep user computations with
  /// angles from inadvertently ending up in the wrong quadrant. A type that
  /// conforms to the `FloatingPoint` protocol provides the value for `pi` at
  /// its best possible precision.
  ///
  ///     print(Double.pi)
  ///     // Prints "3.14159265358979"
  static var pi: Self { get }

  // NOTE: Rationale for "ulp" instead of "epsilon":
  // We do not use that name because it is ambiguous at best and misleading
  // at worst:
  //
  // - Historically several definitions of "machine epsilon" have commonly
  //   been used, which differ by up to a factor of two or so. By contrast
  //   "ulp" is a term with a specific unambiguous definition.
  //
  // - Some languages have used "epsilon" to refer to wildly different values,
  //   such as `leastNonzeroMagnitude`.
  //
  // - Inexperienced users often believe that "epsilon" should be used as a
  //   tolerance for floating-point comparisons, because of the name. It is
  //   nearly always the wrong value to use for this purpose.

  /// The unit in the last place of this value.
  ///
  /// This is the unit of the least significant digit in this value's
  /// significand. For most numbers `x`, this is the difference between `x`
  /// and the next greater (in magnitude) representable number. There are some
  /// edge cases to be aware of:
  ///
  /// - If `x` is not a finite number, then `x.ulp` is NaN.
  /// - If `x` is very small in magnitude, then `x.ulp` may be a subnormal
  ///   number. If a type does not support subnormals, `x.ulp` may be rounded
  ///   to zero.
  /// - `greatestFiniteMagnitude.ulp` is a finite number, even though the next
  ///   greater representable value is `infinity`.
  ///
  /// This quantity, or a related quantity, is sometimes called *epsilon* or
  /// *machine epsilon.* Avoid that name because it has different meanings in
  /// different languages, which can lead to confusion, and because it
  /// suggests that it is a good tolerance to use for comparisons, which it
  /// almost never is.
  var ulp: Self { get }

  /// The unit in the last place of 1.0.
  ///
  /// The positive difference between 1.0 and the next greater representable
  /// number. The `ulpOfOne` constant corresponds to the C macros
  /// `FLT_EPSILON`, `DBL_EPSILON`, and others with a similar purpose.
  static var ulpOfOne: Self { get }

  /// The least positive normal number.
  ///
  /// This value compares less than or equal to all positive normal numbers.
  /// There may be smaller positive numbers, but they are *subnormal*, meaning
  /// that they are represented with less precision than normal numbers.
  ///
  /// This value corresponds to type-specific C macros such as `FLT_MIN` and
  /// `DBL_MIN`. The naming of those macros is slightly misleading, because
  /// subnormals, zeros, and negative numbers are smaller than this value.
  static var leastNormalMagnitude: Self { get }

  /// The least positive number.
  ///
  /// This value compares less than or equal to all positive numbers, but
  /// greater than zero. If the type supports subnormal values,
  /// `leastNonzeroMagnitude` is smaller than `leastNormalMagnitude`;
  /// otherwise they are equal.
  static var leastNonzeroMagnitude: Self { get }

  /// The sign of the floating-point value.
  ///
  /// The `sign` property is `.minus` if the value's signbit is set, and
  /// `.plus` otherwise. For example:
  ///
  ///     let x = -33.375
  ///     // x.sign == .minus
  ///
  /// Do not use this property to check whether a floating point value is
  /// negative. For a value `x`, the comparison `x.sign == .minus` is not
  /// necessarily the same as `x < 0`. In particular, `x.sign == .minus` if
  /// `x` is -0, and while `x < 0` is always `false` if `x` is NaN, `x.sign`
  /// could be either `.plus` or `.minus`.
  var sign: FloatingPointSign { get }

  /// The exponent of the floating-point value.
  ///
  /// The *exponent* of a floating-point value is the integer part of the
  /// logarithm of the value's magnitude. For a value `x` of a floating-point
  /// type `F`, the magnitude can be calculated as the following, where `**`
  /// is exponentiation:
  ///
  ///     let magnitude = x.significand * F.radix ** x.exponent
  ///
  /// In the next example, `y` has a value of `21.5`, which is encoded as
  /// `1.34375 * 2 ** 4`. The significand of `y` is therefore 1.34375.
  ///
  ///     let y: Double = 21.5
  ///     // y.significand == 1.34375
  ///     // y.exponent == 4
  ///     // Double.radix == 2
  ///
  /// The `exponent` property has the following edge cases:
  ///
  /// - If `x` is zero, then `x.exponent` is `Int.min`.
  /// - If `x` is +/-infinity or NaN, then `x.exponent` is `Int.max`
  ///
  /// This property implements the `logB` operation defined by the [IEEE 754
  /// specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  var exponent: Exponent { get }

  /// The significand of the floating-point value.
  ///
  /// The magnitude of a floating-point value `x` of type `F` can be calculated
  /// by using the following formula, where `**` is exponentiation:
  ///
  ///     let magnitude = x.significand * F.radix ** x.exponent
  ///
  /// In the next example, `y` has a value of `21.5`, which is encoded as
  /// `1.34375 * 2 ** 4`. The significand of `y` is therefore 1.34375.
  ///
  ///     let y: Double = 21.5
  ///     // y.significand == 1.34375
  ///     // y.exponent == 4
  ///     // Double.radix == 2
  ///
  /// If a type's radix is 2, then for finite nonzero numbers, the significand
  /// is in the range `1.0 ..< 2.0`. For other values of `x`, `x.significand`
  /// is defined as follows:
  ///
  /// - If `x` is zero, then `x.significand` is 0.0.
  /// - If `x` is infinity, then `x.significand` is 1.0.
  /// - If `x` is NaN, then `x.significand` is NaN.
  /// - Note: The significand is frequently also called the *mantissa*, but
  ///   significand is the preferred terminology in the [IEEE 754
  ///   specification][spec], to allay confusion with the use of mantissa for
  ///   the fractional part of a logarithm.
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  var significand: Self { get }

  /// Returns the sum of this value and the given value, rounded to a
  /// representable value.
  ///
  /// This method serves as the basis for the addition operator (`+`). For
  /// example:
  ///
  ///     let x = 1.5
  ///     print(x.adding(2.25))
  ///     // Prints "3.75"
  ///     print(x + 2.25)
  ///     // Prints "3.75"
  ///
  /// The `adding(_:)` method implements the addition operation defined by the
  /// [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameter other: The value to add.
  /// - Returns: The sum of this value and `other`, rounded to a representable
  ///   value.
  ///
  /// - SeeAlso: `add(_:)`
  func adding(_ other: Self) -> Self

  /// Adds the given value to this value in place, rounded to a representable
  /// value.
  ///
  /// This method serves as the basis for the in-place addition operator
  /// (`+=`). For example:
  ///
  ///     var (x, y) = (2.25, 2.25)
  ///     x.add(7.0)
  ///     // x == 9.25
  ///     y += 7.0
  ///     // y == 9.25
  ///
  /// - Parameter other: The value to add.
  ///
  /// - SeeAlso: `adding(_:)`
  mutating func add(_ other: Self)

  /// Returns the additive inverse of this value.
  ///
  /// The result is always exact. This method serves as the basis for the
  /// negation operator (prefixed `-`). For example:
  ///
  ///     let x = 21.5
  ///     let y = x.negated()
  ///     // y == -21.5
  ///
  /// - Returns: The additive inverse of this value.
  ///
  /// - SeeAlso: `negate()`
  func negated() -> Self

  /// Replaces this value with its additive inverse.
  ///
  /// The result is always exact. This example uses the `negate()` method to
  /// negate the value of the variable `x`:
  ///
  ///     var x = 21.5
  ///     x.negate()
  ///     // x == -21.5
  ///
  /// - SeeAlso: `negated()`
  mutating func negate()

  /// Returns the difference of this value and the given value, rounded to a
  /// representable value.
  ///
  /// This method serves as the basis for the subtraction operator (`-`). For
  /// example:
  ///
  ///     let x = 7.5
  ///     print(x.subtracting(2.25))
  ///     // Prints "5.25"
  ///     print(x - 2.25)
  ///     // Prints "5.25"
  ///
  /// The `subtracting(_:)` method implements the subtraction operation
  /// defined by the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameter other: The value to subtract from this value.
  /// - Returns: The difference of this value and `other`, rounded to a
  ///   representable value.
  ///
  /// - SeeAlso: `subtract(_:)`
  func subtracting(_ other: Self) -> Self

  /// Subtracts the given value from this value in place, rounding to a
  /// representable value.
  ///
  /// This method serves as the basis for the in-place subtraction operator
  /// (`-=`). For example:
  ///
  ///     var (x, y) = (7.5, 7.5)
  ///     x.subtract(2.25)
  ///     // x == 5.25
  ///     y -= 2.25
  ///     // y == 5.25
  ///
  /// - Parameter other: The value to subtract.
  ///
  /// - SeeAlso: `subtracting(_:)`
  mutating func subtract(_ other: Self)

  /// Returns the product of this value and the given value, rounded to a
  /// representable value.
  ///
  /// This method serves as the basis for the multiplication operator (`*`).
  /// For example:
  ///
  ///     let x = 7.5
  ///     print(x.multiplied(by: 2.25))
  ///     // Prints "16.875"
  ///     print(x * 2.25)
  ///     // Prints "16.875"
  ///
  /// The `multiplied(by:)` method implements the multiplication operation
  /// defined by the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameter other: The value to multiply by this value.
  /// - Returns: The product of this value and `other`, rounded to a
  ///   representable value.
  ///
  /// - SeeAlso: `multiply(by:)`
  func multiplied(by other: Self) -> Self

  /// Multiplies this value by the given value in place, rounding to a
  /// representable value.
  ///
  /// This method serves as the basis for the in-place multiplication operator
  /// (`*=`). For example:
  ///
  ///     var (x, y) = (7.5, 7.5)
  ///     x.multiply(by: 2.25)
  ///     // x == 16.875
  ///     y *= 2.25
  ///     // y == 16.875
  ///
  /// - Parameter other: The value to multiply by this value.
  ///
  /// - SeeAlso: `multiplied(by:)`
  mutating func multiply(by other: Self)

  /// Returns the quotient of this value and the given value, rounded to a
  /// representable value.
  ///
  /// This method serves as the basis for the division operator (`/`). For
  /// example:
  ///
  ///     let x = 7.5
  ///     let y = x.divided(by: 2.25)
  ///     // y == 16.875
  ///     let z = x * 2.25
  ///     // z == 16.875
  ///
  /// The `divided(by:)` method implements the division operation
  /// defined by the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameter other: The value to use when dividing this value.
  /// - Returns: The quotient of this value and `other`, rounded to a
  ///   representable value.
  ///
  /// - SeeAlso: `divide(by:)`
  func divided(by other: Self) -> Self

  /// Divides this value by the given value in place, rounding to a
  /// representable value.
  ///
  /// This method serves as the basis for the in-place division operator
  /// (`/=`). For example:
  ///
  ///     var (x, y) = (16.875, 16.875)
  ///     x.divide(by: 2.25)
  ///     // x == 7.5
  ///     y /= 2.25
  ///     // y == 7.5
  ///
  /// - Parameter other: The value to use when dividing this value.
  ///
  /// - SeeAlso: `divided(by:)`
  mutating func divide(by other: Self)

  /// Returns the remainder of this value divided by the given value.
  ///
  /// For two finite values `x` and `y`, the remainder `r` of dividing `x` by
  /// `y` satisfies `x == y * q + r`, where `q` is the integer nearest to
  /// `x / y`. If `x / y` is exactly halfway between two integers, `q` is
  /// chosen to be even. Note that `q` is *not* `x / y` computed in
  /// floating-point arithmetic, and that `q` may not be representable in any
  /// available integer type.
  ///
  /// The following example calculates the remainder of dividing 8.625 by 0.75:
  ///
  ///     let x = 8.625
  ///     print(x / 0.75)
  ///     // Prints "11.5"
  ///
  ///     let q = (x / 0.75).rounded(.toNearestOrEven)
  ///     // q == 12.0
  ///     let r = x.remainder(dividingBy: 0.75)
  ///     // r == -0.375
  ///
  ///     let x1 = 0.75 * q + r
  ///     // x1 == 8.625
  ///
  /// If this value and `other` are finite numbers, the remainder is in the
  /// closed range `-abs(other / 2)...abs(other / 2)`. The
  /// `remainder(dividingBy:)` method is always exact. This method implements
  /// the remainder operation defined by the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameter other: The value to use when dividing this value.
  /// - Returns: The remainder of this value divided by `other`.
  ///
  /// - SeeAlso: `formRemainder(dividingBy:)`,
  ///   `truncatingRemainder(dividingBy:)`
  func remainder(dividingBy other: Self) -> Self

  /// Replaces this value with the remainder of itself divided by the given
  /// value.
  ///
  /// For two finite values `x` and `y`, the remainder `r` of dividing `x` by
  /// `y` satisfies `x == y * q + r`, where `q` is the integer nearest to
  /// `x / y`. If `x / y` is exactly halfway between two integers, `q` is
  /// chosen to be even. Note that `q` is *not* `x / y` computed in
  /// floating-point arithmetic, and that `q` may not be representable in any
  /// available integer type.
  ///
  /// The following example calculates the remainder of dividing 8.625 by 0.75:
  ///
  ///     var x = 8.625
  ///     print(x / 0.75)
  ///     // Prints "11.5"
  ///
  ///     let q = (x / 0.75).rounded(.toNearestOrEven)
  ///     // q == 12.0
  ///     x.formRemainder(dividingBy: 0.75)
  ///     // x == -0.375
  ///
  ///     let x1 = 0.75 * q + x
  ///     // x1 == 8.625
  ///
  /// If this value and `other` are finite numbers, the remainder is in the
  /// closed range `-abs(other / 2)...abs(other / 2)`. The
  /// `remainder(dividingBy:)` method is always exact.
  ///
  /// - Parameter other: The value to use when dividing this value.
  ///
  /// - SeeAlso: `remainder(dividingBy:)`,
  ///   `formTruncatingRemainder(dividingBy:)`
  mutating func formRemainder(dividingBy other: Self)

  /// Returns the remainder of this value divided by the given value using
  /// truncating division.
  ///
  /// Performing truncating division with floating-point values results in a
  /// truncated integer quotient and a remainder. For values `x` and `y` and
  /// their truncated integer quotient `q`, the remainder `r` satisfies
  /// `x == y * q + r`.
  ///
  /// The following example calculates the truncating remainder of dividing
  /// 8.625 by 0.75:
  ///
  ///     let x = 8.625
  ///     print(x / 0.75)
  ///     // Prints "11.5"
  ///
  ///     let q = (x / 0.75).rounded(.towardZero)
  ///     // q == 11.0
  ///     let r = x.truncatingRemainder(dividingBy: 0.75)
  ///     // r == 0.375
  ///
  ///     let x1 = 0.75 * q + r
  ///     // x1 == 8.625
  ///
  /// If this value and `other` are both finite numbers, the truncating
  /// remainder has the same sign as this value and is strictly smaller in
  /// magnitude than `other`. The `truncatingRemainder(dividingBy:)` method
  /// is always exact.
  ///
  /// - Parameter other: The value to use when dividing this value.
  /// - Returns: The remainder of this value divided by `other` using
  ///   truncating division.
  ///
  /// - SeeAlso: `formTruncatingRemainder(dividingBy:)`,
  ///   `remainder(dividingBy:)`
  func truncatingRemainder(dividingBy other: Self) -> Self

  /// Replaces this value with the remainder of itself divided by the given
  /// value using truncating division.
  ///
  /// Performing truncating division with floating-point values results in a
  /// truncated integer quotient and a remainder. For values `x` and `y` and
  /// their truncated integer quotient `q`, the remainder `r` satisfies
  /// `x == y * q + r`.
  ///
  /// The following example calculates the truncating remainder of dividing
  /// 8.625 by 0.75:
  ///
  ///     var x = 8.625
  ///     print(x / 0.75)
  ///     // Prints "11.5"
  ///
  ///     let q = (x / 0.75).rounded(.towardZero)
  ///     // q == 11.0
  ///     x.formTruncatingRemainder(dividingBy: 0.75)
  ///     // x == 0.375
  ///
  ///     let x1 = 0.75 * q + x
  ///     // x1 == 8.625
  ///
  /// If this value and `other` are both finite numbers, the truncating
  /// remainder has the same sign as this value and is strictly smaller in
  /// magnitude than `other`. The `formTruncatingRemainder(dividingBy:)`
  /// method is always exact.
  ///
  /// - Parameter other: The value to use when dividing this value.
  ///
  /// - SeeAlso: `truncatingRemainder(dividingBy:)`,
  ///   `formRemainder(dividingBy:)`
  mutating func formTruncatingRemainder(dividingBy other: Self)

  /// Returns the square root of the value, rounded to a representable value.
  ///
  /// The following example declares a function that calculates the length of
  /// the hypotenuse of a right triangle given its two perpendicular sides.
  ///
  ///     func hypotenuse(_ a: Double, _ b: Double) -> Double {
  ///         return (a * a + b * b).squareRoot()
  ///     }
  ///
  ///     let (dx, dy) = (3.0, 4.0)
  ///     let distance = hypotenuse(dx, dy)
  ///     // distance == 5.0
  ///
  /// - Returns: The square root of the value.
  ///
  /// - SeeAlso: `sqrt(_:)`, `formSquareRoot()`
  func squareRoot() -> Self

  /// Replaces this value with its square root, rounded to a representable
  /// value.
  ///
  /// - SeeAlso: `sqrt(_:)`, `squareRoot()`
  mutating func formSquareRoot()

  /// Returns the result of adding the product of the two given values to this
  /// value, computed without intermediate rounding.
  ///
  /// This method is equivalent to the C `fma` function and implements the
  /// `fusedMultiplyAdd` operation defined by the [IEEE 754
  /// specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameters:
  ///   - lhs: One of the values to multiply before adding to this value.
  ///   - rhs: The other value to multiply.
  /// - Returns: The product of `lhs` and `rhs`, added to this value.
  func addingProduct(_ lhs: Self, _ rhs: Self) -> Self

  /// Adds the product of the two given values to this value in place, computed
  /// without intermediate rounding.
  ///
  /// - Parameters:
  ///   - lhs: One of the values to multiply before adding to this value.
  ///   - rhs: The other value to multiply.
  mutating func addProduct(_ lhs: Self, _ rhs: Self)

  /// Returns the lesser of the two given values.
  ///
  /// This method returns the minimum of two values, preserving order and
  /// eliminating NaN when possible. For two values `x` and `y`, the result of
  /// `minimum(x, y)` is `x` if `x <= y`, `y` if `y < x`, or whichever of `x`
  /// or `y` is a number if the other is a quiet NaN. If both `x` and `y` are
  /// NaN, or either `x` or `y` is a signaling NaN, the result is NaN.
  ///
  ///     Double.minimum(10.0, -25.0)
  ///     // -25.0
  ///     Double.minimum(10.0, .nan)
  ///     // 10.0
  ///     Double.minimum(.nan, -25.0)
  ///     // -25.0
  ///     Double.minimum(.nan, .nan)
  ///     // nan
  ///
  /// The `minimum` method implements the `minNum` operation defined by the
  /// [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameters:
  ///   - x: A floating-point value.
  ///   - y: Another floating-point value.
  /// - Returns: The minimum of `x` and `y`, or whichever is a number if the
  ///   other is NaN.
  static func minimum(_ x: Self, _ y: Self) -> Self

  /// Returns the greater of the two given values.
  ///
  /// This method returns the maximum of two values, preserving order and
  /// eliminating NaN when possible. For two values `x` and `y`, the result of
  /// `maximum(x, y)` is `x` if `x > y`, `y` if `x <= y`, or whichever of `x`
  /// or `y` is a number if the other is a quiet NaN. If both `x` and `y` are
  /// NaN, or either `x` or `y` is a signaling NaN, the result is NaN.
  ///
  ///     Double.maximum(10.0, -25.0)
  ///     // 10.0
  ///     Double.maximum(10.0, .nan)
  ///     // 10.0
  ///     Double.maximum(.nan, -25.0)
  ///     // -25.0
  ///     Double.maximum(.nan, .nan)
  ///     // nan
  ///
  /// The `maximum` method implements the `maxNum` operation defined by the
  /// [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameters:
  ///   - x: A floating-point value.
  ///   - y: Another floating-point value.
  /// - Returns: The greater of `x` and `y`, or whichever is a number if the
  ///   other is NaN.
  static func maximum(_ x: Self, _ y: Self) -> Self

  /// Returns the value with lesser magnitude.
  ///
  /// This method returns the value with lesser magnitude of the two given
  /// values, preserving order and eliminating NaN when possible. For two
  /// values `x` and `y`, the result of `minimumMagnitude(x, y)` is `x` if
  /// `x.magnitude <= y.magnitude`, `y` if `y.magnitude < x.magnitude`, or
  /// whichever of `x` or `y` is a number if the other is a quiet NaN. If both
  /// `x` and `y` are NaN, or either `x` or `y` is a signaling NaN, the result
  /// is NaN.
  ///
  ///     Double.minimumMagnitude(10.0, -25.0)
  ///     // 10.0
  ///     Double.minimumMagnitude(10.0, .nan)
  ///     // 10.0
  ///     Double.minimumMagnitude(.nan, -25.0)
  ///     // -25.0
  ///     Double.minimumMagnitude(.nan, .nan)
  ///     // nan
  ///
  /// The `minimumMagnitude` method implements the `minNumMag` operation
  /// defined by the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameters:
  ///   - x: A floating-point value.
  ///   - y: Another floating-point value.
  /// - Returns: Whichever of `x` or `y` has lesser magnitude, or whichever is
  ///   a number if the other is NaN.
  static func minimumMagnitude(_ x: Self, _ y: Self) -> Self

  /// Returns the value with greater magnitude.
  ///
  /// This method returns the value with greater magnitude of the two given
  /// values, preserving order and eliminating NaN when possible. For two
  /// values `x` and `y`, the result of `maximumMagnitude(x, y)` is `x` if
  /// `x.magnitude > y.magnitude`, `y` if `x.magnitude <= y.magnitude`, or
  /// whichever of `x` or `y` is a number if the other is a quiet NaN. If both
  /// `x` and `y` are NaN, or either `x` or `y` is a signaling NaN, the result
  /// is NaN.
  ///
  ///     Double.maximumMagnitude(10.0, -25.0)
  ///     // -25.0
  ///     Double.maximumMagnitude(10.0, .nan)
  ///     // 10.0
  ///     Double.maximumMagnitude(.nan, -25.0)
  ///     // -25.0
  ///     Double.maximumMagnitude(.nan, .nan)
  ///     // nan
  ///
  /// The `maximumMagnitude` method implements the `maxNumMag` operation
  /// defined by the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameters:
  ///   - x: A floating-point value.
  ///   - y: Another floating-point value.
  /// - Returns: Whichever of `x` or `y` has greater magnitude, or whichever is
  ///   a number if the other is NaN.
  static func maximumMagnitude(_ x: Self, _ y: Self) -> Self

  /// Returns this value rounded to an integral value using the specified
  /// rounding rule.
  ///
  /// The following example rounds a value using four different rounding rules:
  ///
  ///     let x = 6.5
  ///
  ///     // Equivalent to the C 'round' function:
  ///     print(x.rounded(.toNearestOrAwayFromZero))
  ///     // Prints "7.0"
  ///
  ///     // Equivalent to the C 'trunc' function:
  ///     print(x.rounded(.towardZero))
  ///     // Prints "6.0"
  ///
  ///     // Equivalent to the C 'ceil' function:
  ///     print(x.rounded(.up))
  ///     // Prints "7.0"
  ///
  ///     // Equivalent to the C 'floor' function:
  ///     print(x.rounded(.down))
  ///     // Prints "6.0"
  ///
  /// For more information about the available rounding rules, see the
  /// `FloatingPointRoundingRule` enumeration. To round a value using the
  /// default "schoolbook rounding", you can use the shorter `rounded()`
  /// method instead.
  ///
  ///     print(x.rounded())
  ///     // Prints "7.0"
  ///
  /// - Parameter rule: The rounding rule to use.
  /// - Returns: The integral value found by rounding using `rule`.
  ///
  /// - SeeAlso: `rounded()`, `round(_:)`, `FloatingPointRoundingRule`
  func rounded(_ rule: FloatingPointRoundingRule) -> Self

  /// Rounds the value to an integral value using the specified rounding rule.
  ///
  /// The following example rounds a value using four different rounding rules:
  ///
  ///     // Equivalent to the C 'round' function:
  ///     var w = 6.5
  ///     w.round(.toNearestOrAwayFromZero)
  ///     // w == 7.0
  ///
  ///     // Equivalent to the C 'trunc' function:
  ///     var x = 6.5
  ///     x.round(.towardZero)
  ///     // x == 6.0
  ///
  ///     // Equivalent to the C 'ceil' function:
  ///     var y = 6.5
  ///     y.round(.up)
  ///     // y == 7.0
  ///
  ///     // Equivalent to the C 'floor' function:
  ///     var z = 6.5
  ///     z.round(.down)
  ///     // z == 6.0
  ///
  /// For more information about the available rounding rules, see the
  /// `FloatingPointRoundingRule` enumeration. To round a value using the
  /// default "schoolbook rounding", you can use the shorter `round()` method
  /// instead.
  ///
  ///     var w1 = 6.5
  ///     w1.round()
  ///     // w1 == 7.0
  ///
  /// - Parameter rule: The rounding rule to use.
  ///
  /// - SeeAlso: `round()`, `rounded(_:)`, `FloatingPointRoundingRule`
  mutating func round(_ rule: FloatingPointRoundingRule)

  /// The least representable value that compares greater than this value.
  ///
  /// For any finite value `x`, `x.nextUp` is greater than `x`. For `nan` or
  /// `infinity`, `x.nextUp` is `x` itself. The following special cases also
  /// apply:
  ///
  /// - If `x` is `-infinity`, then `x.nextUp` is `-greatestFiniteMagnitude`.
  /// - If `x` is `-leastNonzeroMagnitude`, then `x.nextUp` is `-0.0`.
  /// - If `x` is zero, then `x.nextUp` is `leastNonzeroMagnitude`.
  /// - If `x` is `greatestFiniteMagnitude`, then `x.nextUp` is `infinity`.
  var nextUp: Self { get }

  /// The greatest representable value that compares less than this value.
  ///
  /// For any finite value `x`, `x.nextDown` is greater than `x`. For `nan` or
  /// `-infinity`, `x.nextDown` is `x` itself. The following special cases
  /// also apply:
  ///
  /// - If `x` is `infinity`, then `x.nextDown` is `greatestFiniteMagnitude`.
  /// - If `x` is `leastNonzeroMagnitude`, then `x.nextDown` is `0.0`.
  /// - If `x` is zero, then `x.nextDown` is `-leastNonzeroMagnitude`.
  /// - If `x` is `-greatestFiniteMagnitude`, then `x.nextDown` is `-infinity`.
  var nextDown: Self { get }

  /// Returns a Boolean value indicating whether this instance is equal to the
  /// given value.
  ///
  /// This method serves as the basis for the equal-to operator (`==`) for
  /// floating-point values. When comparing two values with this method, `-0`
  /// is equal to `+0`. NaN is not equal to any value, including itself. For
  /// example:
  ///
  ///     let x = 15.0
  ///     x.isEqual(to: 15.0)
  ///     // true
  ///     x.isEqual(to: .nan)
  ///     // false
  ///     Double.nan.isEqual(to: .nan)
  ///     // false
  ///
  /// The `isEqual(to:)` method implements the equality predicate defined by
  /// the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameter other: The value to compare with this value.
  /// - Returns: `true` if `other` has the same value as this instance;
  ///   otherwise, `false`.
  func isEqual(to other: Self) -> Bool

  /// Returns a Boolean value indicating whether this instance is less than the
  /// given value.
  ///
  /// This method serves as the basis for the less-than operator (`<`) for
  /// floating-point values. Some special cases apply:
  ///
  /// - Because NaN compares not less than nor greater than any value, this
  ///   method returns `false` when called on NaN or when NaN is passed as
  ///   `other`.
  /// - `-infinity` compares less than all values except for itself and NaN.
  /// - Every value except for NaN and `+infinity` compares less than
  ///   `+infinity`.
  ///
  ///     let x = 15.0
  ///     x.isLess(than: 20.0)
  ///     // true
  ///     x.isLess(than: .nan)
  ///     // false
  ///     Double.nan.isLess(than: x)
  ///     // false
  ///
  /// The `isLess(than:)` method implements the less-than predicate defined by
  /// the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameter other: The value to compare with this value.
  /// - Returns: `true` if `other` is less than this value; otherwise, `false`.
  func isLess(than other: Self) -> Bool

  /// Returns a Boolean value indicating whether this instance is less than or
  /// equal to the given value.
  ///
  /// This method serves as the basis for the less-than-or-equal-to operator
  /// (`<=`) for floating-point values. Some special cases apply:
  ///
  /// - Because NaN is incomparable with any value, this method returns `false`
  ///   when called on NaN or when NaN is passed as `other`.
  /// - `-infinity` compares less than or equal to all values except NaN.
  /// - Every value except NaN compares less than or equal to `+infinity`.
  ///
  ///     let x = 15.0
  ///     x.isLessThanOrEqualTo(20.0)
  ///     // true
  ///     x.isLessThanOrEqualTo(.nan)
  ///     // false
  ///     Double.nan.isLessThanOrEqualTo(x)
  ///     // false
  ///
  /// The `isLessThanOrEqualTo(_:)` method implements the less-than-or-equal
  /// predicate defined by the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameter other: The value to compare with this value.
  /// - Returns: `true` if `other` is less than this value; otherwise, `false`.
  func isLessThanOrEqualTo(_ other: Self) -> Bool

  /// Returns a Boolean value indicating whether this instance should precede the
  /// given value in an ascending sort.
  ///
  /// This relation is a refinement of the less-than-or-equal-to operator
  /// (`<=`) that provides a total order on all values of the type, including
  /// noncanonical encodings, signed zeros, and NaNs. Because it is used much
  /// less frequently than the usual comparisons, there is no operator form of
  /// this relation.
  ///
  /// The following example uses `isTotallyOrdered(below:)` to sort an array of
  /// floating-point values, including some that are NaN:
  ///
  ///     var numbers = [2.5, 21.25, 3.0, .nan, -9.5]
  ///     numbers.sort { $0.isTotallyOrdered(below: $1) }
  ///     // numbers == [-9.5, 2.5, 3.0, 21.25, nan]
  ///
  /// The `isTotallyOrdered(belowOrEqualTo:)` method implements the total order
  /// relation as defined by the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameter other: A floating-point value to compare to this value.
  /// - Returns: `true` if this value is ordered below `other` in a total
  ///   ordering of the floating-point type; otherwise, `false`.
  func isTotallyOrdered(belowOrEqualTo other: Self) -> Bool

  /// A Boolean value indicating whether this instance is normal.
  ///
  /// A *normal* value is a finite number that uses the full precision
  /// available to values of a type. Zero is neither a normal nor a subnormal
  /// number.
  var isNormal: Bool { get }

  /// A Boolean value indicating whether this instance is finite.
  ///
  /// All values other than NaN and infinity are considered finite, whether
  /// normal or subnormal.
  var isFinite: Bool { get }

  /// A Boolean value indicating whether the instance is equal to zero.
  ///
  /// The `isZero` property of a value `x` is `true` when `x` represents either
  /// `-0.0` or `+0.0`. `x.isZero` is equivalent to the following comparison:
  /// `x == 0.0`.
  ///
  ///     let x = -0.0
  ///     x.isZero        // true
  ///     x == 0.0        // true
  var isZero: Bool { get }

  /// A Boolean value indicating whether the instance is subnormal.
  ///
  /// A *subnormal* value is a nonzero number that has a lesser magnitude than
  /// the smallest normal number. Subnormal values do not use the full
  /// precision available to values of a type.
  ///
  /// Zero is neither a normal nor a subnormal number. Subnormal numbers are
  /// often called *denormal* or *denormalized*---these are different names
  /// for the same concept.
  var isSubnormal: Bool { get }

  /// A Boolean value indicating whether the instance is infinite.
  ///
  /// Note that `isFinite` and `isInfinite` do not form a dichotomy, because
  /// they are not total: If `x` is `NaN`, then both properties are `false`.
  var isInfinite: Bool { get }

  /// A Boolean value indicating whether the instance is NaN ("not a number").
  ///
  /// Because NaN is not equal to any value, including NaN, use this property
  /// instead of the equal-to operator (`==`) or not-equal-to operator (`!=`)
  /// to test whether a value is or is not NaN. For example:
  ///
  ///     let x = 0.0
  ///     let y = x * .infinity
  ///     // y is a NaN
  ///
  ///     // Comparing with the equal-to operator never returns 'true'
  ///     print(x == Double.nan)
  ///     // Prints "false"
  ///     print(y == Double.nan)
  ///     // Prints "false"
  ///
  ///     // Test with the 'isNaN' property instead
  ///     print(x.isNaN)
  ///     // Prints "false"
  ///     print(y.isNaN)
  ///     // Prints "true"
  ///
  /// This property is `true` for both quiet and signaling NaNs.
  var isNaN: Bool { get }

  /// A Boolean value indicating whether the instance is a signaling NaN.
  ///
  /// Signaling NaNs typically raise the Invalid flag when used in general
  /// computing operations.
  var isSignalingNaN: Bool { get }

  /// The classification of this value.
  ///
  /// A value's `floatingPointClass` property describes its "class" as
  /// described by the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  var floatingPointClass: FloatingPointClassification { get }

  /// A Boolean value indicating whether the instance's representation is in
  /// the canonical form.
  ///
  /// The [IEEE 754 specification][spec] defines a *canonical*, or preferred,
  /// encoding of a floating-point value's representation. Every `Float` or
  /// `Double` value is canonical, but noncanonical values of the `Float80`
  /// type exist, and noncanonical values may exist for other types that
  /// conform to the `FloatingPoint` protocol.
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  var isCanonical: Bool { get }
}

/// The sign of a floating-point value.
public enum FloatingPointSign: Int {
  /// The sign for a positive value.
  case plus

  /// The sign for a negative value.
  case minus
}

/// The IEEE 754 floating-point classes.
public enum FloatingPointClassification {
  /// A signaling NaN ("not a number").
  ///
  /// A signaling NaN sets the floating-point exception status when used in
  /// many floating-point operations.
  case signalingNaN

  /// A silent NaN ("not a number") value.
  case quietNaN

  /// A value equal to `-infinity`.
  case negativeInfinity

  /// A negative value that uses the full precision of the floating-point type.
  ///
  /// - SeeAlso: `FloatingPoint.isNormal`
  case negativeNormal

  /// A negative, nonzero number that does not use the full precision of the
  /// floating-point type.
  ///
  /// - SeeAlso: `FloatingPoint.isSubnormal`
  case negativeSubnormal

  /// A value equal to zero with a negative sign.
  case negativeZero

  /// A value equal to zero with a positive sign.
  case positiveZero

  /// A positive, nonzero number that does not use the full precision of the
  /// floating-point type.
  ///
  /// - SeeAlso: `FloatingPoint.isSubnormal`
  case positiveSubnormal

  /// A positive value that uses the full precision of the floating-point type.
  ///
  /// - SeeAlso: `FloatingPoint.isNormal`
  case positiveNormal

  /// A value equal to `+infinity`.
  case positiveInfinity
}

/// A rule for rounding a floating-point number.
public enum FloatingPointRoundingRule {
  /// Round to the closest allowed value; if two values are equally close, the
  /// one with greater magnitude is chosen.
  ///
  /// This rounding rule is also known as "schoolbook rounding." The following
  /// example shows the results of rounding numbers using this rule:
  ///
  ///     (5.2).rounded(.toNearestOrAwayFromZero)
  ///     // 5.0
  ///     (5.5).rounded(.toNearestOrAwayFromZero)
  ///     // 6.0
  ///     (-5.2).rounded(.toNearestOrAwayFromZero)
  ///     // -5.0
  ///     (-5.5).rounded(.toNearestOrAwayFromZero)
  ///     // -6.0
  ///
  /// This rule is equivalent to the C `round` function and implements the
  /// `roundToIntegralTiesToAway` operation defined by the [IEEE 754
  /// specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  case toNearestOrAwayFromZero

  /// Round to the closest allowed value; if two values are equally close, the
  /// even one is chosen.
  ///
  /// This rounding rule is also known as "bankers rounding," and is the
  /// default IEEE 754 rounding mode for arithmetic. The following example
  /// shows the results of rounding numbers using this rule:
  ///
  ///     (5.2).rounded(.toNearestOrEven)
  ///     // 5.0
  ///     (5.5).rounded(.toNearestOrEven)
  ///     // 6.0
  ///     (4.5).rounded(.toNearestOrEven)
  ///     // 4.0
  ///
  /// This rule implements the `roundToIntegralTiesToEven` operation defined by
  /// the [IEEE 754 specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  case toNearestOrEven

  /// Round to the closest allowed value that is greater than or equal to the
  /// source.
  ///
  /// The following example shows the results of rounding numbers using this
  /// rule:
  ///
  ///     (5.2).rounded(.up)
  ///     // 6.0
  ///     (5.5).rounded(.up)
  ///     // 6.0
  ///     (-5.2).rounded(.up)
  ///     // -5.0
  ///     (-5.5).rounded(.up)
  ///     // -5.0
  ///
  /// This rule is equivalent to the C `ceil` function and implements the
  /// `roundToIntegralTowardPositive` operation defined by the [IEEE 754
  /// specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  case up

  /// Round to the closest allowed value that is less than or equal to the
  /// source.
  ///
  /// The following example shows the results of rounding numbers using this
  /// rule:
  ///
  ///     (5.2).rounded(.down)
  ///     // 5.0
  ///     (5.5).rounded(.down)
  ///     // 5.0
  ///     (-5.2).rounded(.down)
  ///     // -6.0
  ///     (-5.5).rounded(.down)
  ///     // -6.0
  ///
  /// This rule is equivalent to the C `floor` function and implements the
  /// `roundToIntegralTowardNegative` operation defined by the [IEEE 754
  /// specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  case down

  /// Round to the closest allowed value whose magnitude is less than or equal
  /// to that of the source.
  ///
  /// The following example shows the results of rounding numbers using this
  /// rule:
  ///
  ///     (5.2).rounded(.towardZero)
  ///     // 5.0
  ///     (5.5).rounded(.towardZero)
  ///     // 5.0
  ///     (-5.2).rounded(.towardZero)
  ///     // -5.0
  ///     (-5.5).rounded(.towardZero)
  ///     // -5.0
  ///
  /// This rule is equivalent to the C `trunc` function and implements the
  /// `roundToIntegralTowardZero` operation defined by the [IEEE 754
  /// specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  case towardZero

  /// Round to the closest allowed value whose magnitude is greater than or
  /// equal to that of the source.
  ///
  /// The following example shows the results of rounding numbers using this
  /// rule:
  ///
  ///     (5.2).rounded(.awayFromZero)
  ///     // 6.0
  ///     (5.5).rounded(.awayFromZero)
  ///     // 6.0
  ///     (-5.2).rounded(.awayFromZero)
  ///     // -6.0
  ///     (-5.5).rounded(.awayFromZero)
  ///     // -6.0
  case awayFromZero
}

@_transparent
public prefix func + <T : FloatingPoint>(x: T) -> T {
  return x
}

@_transparent
public prefix func - <T : FloatingPoint>(x: T) -> T {
  return x.negated()
}

%{
binary_arithmetic = [
('+', 'adding',      'add',      None),
('-', 'subtracting', 'subtract', None),
('*', 'multiplied',  'multiply', 'by'),
('/', 'divided',     'divide',   'by')
]
}%

%for op in binary_arithmetic:
@_transparent
public func ${op[0]}<T : FloatingPoint>(lhs: T, rhs: T) -> T {
  return lhs.${op[1]}(${op[3]+': ' if op[3] else ''}rhs)
}

@_transparent
public func ${op[0]}=<T : FloatingPoint>(lhs: inout T, rhs: T) {
  return lhs.${op[2]}(${op[3]+': ' if op[3] else ''}rhs)
}

%end

@_transparent
public func == <T : FloatingPoint>(lhs: T, rhs: T) -> Bool {
  return lhs.isEqual(to: rhs)
}

@_transparent
public func < <T : FloatingPoint>(lhs: T, rhs: T) -> Bool {
  return lhs.isLess(than: rhs)
}

@_transparent
public func <= <T : FloatingPoint>(lhs: T, rhs: T) -> Bool {
  return lhs.isLessThanOrEqualTo(rhs)
}

@_transparent
public func > <T : FloatingPoint>(lhs: T, rhs: T) -> Bool {
  return rhs.isLess(than: lhs)
}

@_transparent
public func >= <T : FloatingPoint>(lhs: T, rhs: T) -> Bool {
  return rhs.isLessThanOrEqualTo(lhs)
}

/// A radix-2 (binary) floating-point type.
///
/// The `BinaryFloatingPoint` protocol extends the `FloatingPoint` protocol
/// with operations specific to floating-point binary types, as defined by the
/// [IEEE 754 specification][spec]. `BinaryFloatingPoint` is implemented in
/// the standard library by `Float`, `Double`, and `Float80` where available.
///
/// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
///
/// - SeeAlso: `FloatingPoint`
public protocol BinaryFloatingPoint: FloatingPoint, ExpressibleByFloatLiteral {

  /// A type that represents the encoded significand of a value.
  associatedtype RawSignificand: UnsignedInteger

  /// A type that represents the encoded exponent of a value.
  associatedtype RawExponent: UnsignedInteger

  /// Creates a new instance from the specified sign and bit patterns.
  ///
  /// The values passed as `exponentBitPattern` and `significandBitPattern` are
  /// interpreted in the binary interchange format defined by the [IEEE 754
  /// specification][spec].
  ///
  /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933
  ///
  /// - Parameters:
  ///   - sign: The sign of the new value.
  ///   - exponentBitPattern: The bit pattern to use for the exponent field of
  ///     the new value.
  ///   - significandBitPattern: The bit pattern to use for the significand
  ///     field of the new value.
  init(sign: FloatingPointSign,
       exponentBitPattern: RawExponent,
       significandBitPattern: RawSignificand)

  /// Creates a new instance from the given value, rounded to the closest
  /// possible representation.
  ///
  /// - Parameter value: A floating-point value.
  init(_ value: Float)

  /// Creates a new instance from the given value, rounded to the closest
  /// possible representation.
  ///
  /// - Parameter value: A floating-point value.
  init(_ value: Double)

#if (!os(Windows) || CYGWIN) && (arch(i386) || arch(x86_64))
  /// Creates a new instance from the given value, rounded to the closest
  /// possible representation.
  ///
  /// - Parameter value: A floating-point value.
  init(_ value: Float80)
#endif

  /*  TODO: Implement these once it becomes possible to do so (requires revised
      Integer protocol).
  /// Creates a new instance from the given value, rounded to the closest
  /// possible representation.
  ///
  /// - Parameter value: A floating-point value.
  init<Source: BinaryFloatingPoint>(_ value: Source)

  /// Creates a new instance equivalent to the exact given value.
  ///
  /// If the value you pass as `value` can't be represented exactly, the result
  /// of this initializer is `nil`.
  ///
  /// - Parameter value: A floating-point value to represent.
  init?<Source: BinaryFloatingPoint>(exactly value: Source)
  */

  /// The number of bits used to represent the type's exponent.
  ///
  /// A binary floating-point type's `exponentBitCount` imposes a limit on the
  /// range of the exponent for normal, finite values. The *exponent bias* of
  /// a type `F` can be calculated as the following, where `**` is
  /// exponentiation:
  ///
  ///     let bias = 2 ** (F.exponentBitCount - 1) - 1
  ///
  /// The least normal exponent for values of the type `F` is `1 - bias`, and
  /// the largest finite exponent is `bias`. An all-zeros exponent is reserved
  /// for subnormals and zeros, and an all-ones exponent is reserved for
  /// infinity and NaN.
  ///
  /// For example, the `Float` type has an `exponentBitCount` of 8, which gives
  /// an exponent bias of `127` by the calculation above.
  ///
  ///     let bias = 2 ** (Float.exponentBitCount - 1) - 1
  ///     // bias == 127
  ///     print(Float.greatestFiniteMagnitude.exponent)
  ///     // Prints "127"
  ///     print(Float.leastNormalMagnitude.exponent)
  ///     // Prints "-126"
  static var exponentBitCount: Int { get }

  /// The available number of fractional significand bits.
  ///
  /// For fixed-width floating-point types, this is the actual number of
  /// fractional significand bits.
  ///
  /// For extensible floating-point types, `significandBitCount` should be the
  /// maximum allowed significand width (without counting any leading integral
  /// bit of the significand). If there is no upper limit, then
  /// `significandBitCount` should be `Int.max`.
  ///
  /// Note that `Float80.significandBitCount` is 63, even though 64 bits are
  /// used to store the significand in the memory representation of a
  /// `Float80` (unlike other floating-point types, `Float80` explicitly
  /// stores the leading integral significand bit, but the
  /// `BinaryFloatingPoint` APIs provide an abstraction so that users don't
  /// need to be aware of this detail).
  static var significandBitCount: Int { get }

  /// The raw encoding of the value's exponent field.
  ///
  /// This value is unadjusted by the type's exponent bias.
  ///
  /// - SeeAlso: `exponentBitCount`
  var exponentBitPattern: RawExponent { get }

  /// The raw encoding of the value's significand field.
  ///
  /// The `significandBitPattern` property does not include the leading
  /// integral bit of the significand, even for types like `Float80` that
  /// store it explicitly.
  var significandBitPattern: RawSignificand { get }

  /// The floating-point value with the same sign and exponent as this value,
  /// but with a significand of 1.0.
  ///
  /// A *binade* is a set of binary floating-point values that all have the
  /// same sign and exponent. The `binade` property is a member of the same
  /// binade as this value, but with a unit significand.
  ///
  /// In this example, `x` has a value of `21.5`, which is stored as
  /// `1.34375 * 2**4`, where `**` is exponentiation. Therefore, `x.binade` is
  /// equal to `1.0 * 2**4`, or `16.0`.
  ///
  ///     let x = 21.5
  ///     // x.significand == 1.34375
  ///     // x.exponent == 4
  ///
  ///     let y = x.binade
  ///     // y == 16.0
  ///     // y.significand == 1.0
  ///     // y.exponent == 4
  var binade: Self { get }

  /// The number of bits required to represent the value's significand.
  ///
  /// If this value is a finite nonzero number, `significandWidth` is the
  /// number of fractional bits required to represent the value of
  /// `significand`; otherwise, `significandWidth` is -1. The value of
  /// `significandWidth` is always -1 or between zero and
  /// `significandBitCount`. For example:
  ///
  /// - For any representable power of two, `significandWidth` is zero, because
  ///   `significand` is `1.0`.
  /// - If `x` is 10, `x.significand` is `1.01` in binary, so
  ///   `x.significandWidth` is 2.
  /// - If `x` is Float.pi, `x.significand` is `1.10010010000111111011011` in
  ///   binary, and `x.significandWidth` is 23.
  var significandWidth: Int { get }

  /*  TODO: Implement these once it becomes possible to do so. (Requires
   *  revised Integer protocol).
  func isEqual<Other: BinaryFloatingPoint>(to other: Other) -> Bool

  func isLess<Other: BinaryFloatingPoint>(than other: Other) -> Bool

  func isLessThanOrEqualTo<Other: BinaryFloatingPoint>(other: Other) -> Bool

  func isTotallyOrdered<Other: BinaryFloatingPoint>(belowOrEqualTo other: Other) -> Bool
  */
}

extension FloatingPoint {

  public static var ulpOfOne: Self {
    return Self(1).ulp
  }

  @_transparent
  public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
    var lhs = self
    lhs.round(rule)
    return lhs
  }

  /// Returns this value rounded to an integral value using "schoolbook
  /// rounding."
  ///
  /// The `rounded()` method uses the `.toNearestOrAwayFromZero` rounding rule,
  /// where a value halfway between two integral values is rounded to the one
  /// with greater magnitude. The following example rounds several values
  /// using this default rule:
  ///
  ///     (5.2).rounded()
  ///     // 5.0
  ///     (5.5).rounded()
  ///     // 6.0
  ///     (-5.2).rounded()
  ///     // -5.0
  ///     (-5.5).rounded()
  ///     // -6.0
  ///
  /// To specify an alternative rule for rounding, use the `rounded(_:)` method
  /// instead.
  ///
  /// - Returns: The nearest integral value, or, if two integral values are
  ///   equally close, the integral value with greater magnitude.
  ///
  /// - SeeAlso: `rounded(_:)`, `round()`, `FloatingPointRoundingRule`
  @_transparent
  public func rounded() -> Self {
    return rounded(.toNearestOrAwayFromZero)
  }

  /// Rounds this value to an integral value using "schoolbook rounding."
  ///
  /// The `round()` method uses the `.toNearestOrAwayFromZero` rounding rule,
  /// where a value halfway between two integral values is rounded to the one
  /// with greater magnitude. The following example rounds several values
  /// using this default rule:
  ///
  ///     var x = 5.2
  ///     x.round()
  ///     // x == 5.0
  ///     var y = 5.5
  ///     y.round()
  ///     // y == 6.0
  ///     var z = -5.5
  ///     z.round()
  ///     // z == -6.0
  ///
  /// To specify an alternative rule for rounding, use the `round(_:)` method
  /// instead.
  ///
  /// - SeeAlso: `round(_:)`, `rounded()`, `FloatingPointRoundingRule`
  @_transparent
  public mutating func round() {
    round(.toNearestOrAwayFromZero)
  }

  @_transparent
  public var nextDown: Self {
    return -(-self).nextUp
  }

  @_transparent
  public func truncatingRemainder(dividingBy other: Self) -> Self {
    var lhs = self
    lhs.formTruncatingRemainder(dividingBy: other)
    return lhs
  }

  @_transparent
  public func remainder(dividingBy rhs: Self) -> Self {
    var lhs = self
    lhs.formRemainder(dividingBy: rhs)
    return lhs
  }

  @_transparent
  public func squareRoot( ) -> Self {
    var lhs = self
    lhs.formSquareRoot( )
    return lhs
  }

  @_transparent
  public func addingProduct(_ lhs: Self, _ rhs: Self) -> Self {
    var addend = self
    addend.addProduct(lhs, rhs)
    return addend
  }

  public static func minimum(_ x: Self, _ y: Self) -> Self {
    if x.isSignalingNaN || y.isSignalingNaN {
      //  Produce a quiet NaN matching platform arithmetic behavior.
      return x + y
    }
    if x <= y || y.isNaN { return x }
    return y
  }

  public static func maximum(_ x: Self, _ y: Self) -> Self {
    if x.isSignalingNaN || y.isSignalingNaN {
      //  Produce a quiet NaN matching platform arithmetic behavior.
      return x + y
    }
    if x > y || y.isNaN { return x }
    return y
  }

  public static func minimumMagnitude(_ x: Self, _ y: Self) -> Self {
    if x.isSignalingNaN || y.isSignalingNaN {
      //  Produce a quiet NaN matching platform arithmetic behavior.
      return x + y
    }
    if abs(x) <= abs(y) || y.isNaN { return x }
    return y
  }

  public static func maximumMagnitude(_ x: Self, _ y: Self) -> Self {
    if x.isSignalingNaN || y.isSignalingNaN {
      //  Produce a quiet NaN matching platform arithmetic behavior.
      return x + y
    }
    if abs(x) > abs(y) || y.isNaN { return x }
    return y
  }

  public var floatingPointClass: FloatingPointClassification {
    if isSignalingNaN { return .signalingNaN }
    if isNaN { return .quietNaN }
    if isInfinite { return sign == .minus ? .negativeInfinity : .positiveInfinity }
    if isNormal { return sign == .minus ? .negativeNormal : .positiveNormal }
    if isSubnormal { return sign == .minus ? .negativeSubnormal : .positiveSubnormal }
    return sign == .minus ? .negativeZero : .positiveZero
  }

%for op in binary_arithmetic:
  @_transparent
  public func ${op[1]}(${op[3] if op[3] else '_'} other: Self) -> Self {
    var lhs = self
    lhs.${op[2]}(${op[3]+': ' if op[3] else ''}other)
    return lhs
  }
%end

  @_transparent
  public func negated() -> Self {
    var rhs = self
    rhs.negate()
    return rhs
  }
}

extension BinaryFloatingPoint {

  /// The radix, or base of exponentiation, for this floating-point type.
  ///
  /// All binary floating-point types have a radix of 2. The magnitude of a
  /// floating-point value `x` of type `F` can be calculated by using the
  /// following formula, where `**` is exponentiation:
  ///
  ///     let magnitude = x.significand * F.radix ** x.exponent
  public static var radix: Int { return 2 }

  public init(signOf: Self, magnitudeOf: Self) {
    self.init(sign: signOf.sign,
      exponentBitPattern: magnitudeOf.exponentBitPattern,
      significandBitPattern: magnitudeOf.significandBitPattern)
  }

  public func isTotallyOrdered(belowOrEqualTo other: Self) -> Bool {
    // Quick return when possible.
    if self < other { return true }
    if other > self { return false }
    // Self and other are either equal or unordered.
    // Every negative-signed value (even NaN) is less than every positive-
    // signed value, so if the signs do not match, we simply return the
    // sign bit of self.
    if sign != other.sign { return sign == .minus }
    // Sign bits match; look at exponents.
    if exponentBitPattern > other.exponentBitPattern { return sign == .minus }
    if exponentBitPattern < other.exponentBitPattern { return sign == .plus }
    // Signs and exponents match, look at significands.
    if significandBitPattern > other.significandBitPattern {
      return sign == .minus
    }
    if significandBitPattern < other.significandBitPattern {
      return sign == .plus
    }
    //  Sign, exponent, and significand all match.
    return true
  }


  /*  TODO: uncomment these default implementations when it becomes possible
      to use them.
  //  TODO: The following comparison implementations are not quite correct for
  //  the unusual case where one type has more exponent range and the other
  //  uses more fractional bits, *and* the value with more exponent range is
  //  subnormal when converted to the other type. This is an extremely niche
  //  corner case, however (it cannot occur with the usual IEEE 754 floating-
  //  point types). Nonetheless, this should be fixed someday.
  public func isEqual<Other: BinaryFloatingPoint>(to other: Other) -> Bool {
    if Self.significandBitCount >= Other.significandBitCount {
      return self.isEqual(to: Self(other))
    }
    return other.isEqual(to: Other(self))
  }

  public func isLess<Other: BinaryFloatingPoint>(than other: Other) -> Bool {
    if Self.significandBitCount >= Other.significandBitCount {
      return self.isLess(than: Self(other))
    }
    return Other(self).isLess(than: other)
  }

  public func isLessThanOrEqualTo<Other: BinaryFloatingPoint>(other: Other) -> Bool {
    if Self.significandBitCount >= Other.significandBitCount {
      return self.isLessThanOrEqualTo(Self(other))
    }
    return Other(self).isLessThanOrEqualTo(other)
  }

  public func isTotallyOrdered<Other: BinaryFloatingPoint>(belowOrEqualTo other: Other) -> Bool {
    if Self.significandBitCount >= Other.significandBitCount {
      return self.totalOrder(with: Self(other))
    }
    return Other(self).totalOrder(with: other)
  }
  */
}

/// Returns the absolute value of `x`.
@_transparent
public func abs<T : FloatingPoint>(_ x: T) -> T where T.Magnitude == T {
  return x.magnitude
}

extension FloatingPoint {
  @available(*, unavailable, message: "Use bitPattern property instead")
  public func _toBitPattern() -> UInt {
    fatalError("unavailable")
  }

  @available(*, unavailable, message: "Use init(bitPattern:) instead")
  public static func _fromBitPattern(_ bits: UInt) -> Self {
    fatalError("unavailable")
  }
}

extension BinaryFloatingPoint {
  @available(*, unavailable, renamed: "isSignalingNaN")
  public var isSignaling: Bool {
    fatalError("unavailable")
  }

  @available(*, unavailable, renamed: "nan")
  public var NaN: Bool {
    fatalError("unavailable")
  }
  @available(*, unavailable, renamed: "nan")
  public var quietNaN: Bool {
    fatalError("unavailable")
  }
}

@available(*, unavailable, renamed: "FloatingPoint")
public typealias FloatingPointType = FloatingPoint
