| //===--- FloatingPointTypes.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 |
| // |
| //===----------------------------------------------------------------------===// |
| |
| import SwiftShims |
| |
| %{ |
| from SwiftIntTypes import all_integer_types |
| from SwiftFloatingPointTypes import all_floating_point_types |
| |
| # |
| # Utility code for later in this template |
| # |
| |
| # Number of bits in the Builtin.Word type |
| word_bits = int(CMAKE_SIZEOF_VOID_P) * 8 |
| |
| # Number of bits in integer literals. |
| builtinIntLiteralBits = 2048 |
| }% |
| |
| % for self_type in all_floating_point_types(): |
| %{ |
| Self = self_type.stdlib_name |
| bits = self_type.bits |
| cFuncSuffix = self_type.cFuncSuffix |
| SignificandSize = self_type.significand_size |
| SignificandBitCount = self_type.significand_bits |
| ExponentBitCount = self_type.exponent_bits |
| RawSignificand = 'UInt' + str(SignificandSize) |
| |
| if Self == 'Float': |
| SelfDocComment = '''\ |
| /// A single-precision, floating-point value type.''' |
| |
| elif Self == 'Double': |
| SelfDocComment = '''\ |
| /// A double-precision, floating-point value type.''' |
| |
| elif Self == 'Float80': |
| SelfDocComment = '''\ |
| /// An extended-precision, floating-point value type.''' |
| |
| else: |
| raise ValueError('Unhandled float type.') |
| }% |
| |
| % if bits == 80: |
| #if !os(Windows) && (arch(i386) || arch(x86_64)) |
| % end |
| |
| ${SelfDocComment} |
| @_fixed_layout |
| public struct ${Self} { |
| public // @testable |
| var _value: Builtin.FPIEEE${bits} |
| |
| /// Creates a value initialized to zero. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public init() { |
| let zero: Int64 = 0 |
| self._value = Builtin.sitofp_Int64_FPIEEE${bits}(zero._value) |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public // @testable |
| init(_ _value: Builtin.FPIEEE${bits}) { |
| self._value = _value |
| } |
| } |
| |
| extension ${Self} : CustomStringConvertible { |
| /// A textual representation of the value. |
| @inlinable // FIXME(sil-serialize-all) |
| public var description: String { |
| if isFinite { |
| return _float${bits}ToString(self, debug: false) |
| } else if isNaN { |
| return "nan" |
| } else if sign == .minus { |
| return "-inf" |
| } else { |
| return "inf" |
| } |
| } |
| } |
| |
| extension ${Self} : CustomDebugStringConvertible { |
| /// A textual representation of the value, suitable for debugging. |
| public var debugDescription: String { |
| if isFinite || isNaN { |
| return _float${bits}ToString(self, debug: true) |
| } else if sign == .minus { |
| return "-inf" |
| } else { |
| return "inf" |
| } |
| } |
| } |
| |
| extension ${Self}: BinaryFloatingPoint { |
| |
| /// A type that can represent the absolute value of any possible value of |
| /// this type. |
| public typealias Magnitude = ${Self} |
| |
| /// A type that can represent any written exponent. |
| public typealias Exponent = Int |
| |
| /// A type that represents the encoded significand of a value. |
| public typealias RawSignificand = ${RawSignificand} |
| |
| /// 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" |
| @inlinable // FIXME(sil-serialize-all) |
| public static var exponentBitCount: Int { |
| return ${ExponentBitCount} |
| } |
| |
| /// 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`. |
| %if bits == 80: |
| /// |
| /// `Float80.significandBitCount` is 63, even though 64 bits are used to |
| /// store the significand in the memory representation of a `Float80` |
| /// instance. Unlike other floating-point types, the `Float80` type |
| /// explicitly stores the leading integral significand bit. |
| %end |
| @inlinable // FIXME(sil-serialize-all) |
| public static var significandBitCount: Int { |
| return ${SignificandBitCount} |
| } |
| |
| // Implementation details. |
| @inlinable // FIXME(sil-serialize-all) |
| internal static var _infinityExponent: UInt { |
| @inline(__always) get { return 1 &<< UInt(exponentBitCount) - 1 } |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| internal static var _exponentBias: UInt { |
| @inline(__always) get { return _infinityExponent &>> 1 } |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| internal static var _significandMask: ${RawSignificand} { |
| @inline(__always) get { |
| return 1 &<< ${RawSignificand}(significandBitCount) - 1 |
| } |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| internal static var _quietNaNMask: ${RawSignificand} { |
| @inline(__always) get { |
| return 1 &<< ${RawSignificand}(significandBitCount - 1) |
| } |
| } |
| |
| %if bits != 80: |
| // Conversions to/from integer encoding. These are not part of the |
| // BinaryFloatingPoint prototype because there's no guarantee that an |
| // integer type of the same size actually exists (e.g. Float80). |
| // |
| // If we want them in a protocol at some future point, that protocol should |
| // be "InterchangeFloatingPoint" or "PortableFloatingPoint" or similar, and |
| // apply to IEEE 754 "interchange types". |
| /// The bit pattern of the value's encoding. |
| /// |
| /// The bit pattern matches the binary interchange format defined by the |
| /// [IEEE 754 specification][spec]. |
| /// |
| /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933 |
| @inlinable // FIXME(sil-serialize-all) |
| public var bitPattern: UInt${bits} { |
| return UInt${bits}(Builtin.bitcast_FPIEEE${bits}_Int${bits}(_value)) |
| } |
| |
| /// Creates a new value with the given bit pattern. |
| /// |
| /// The value passed as `bitPattern` is interpreted in the binary interchange |
| /// format defined by the [IEEE 754 specification][spec]. |
| /// |
| /// [spec]: http://ieeexplore.ieee.org/servlet/opac?punumber=4610933 |
| /// |
| /// - Parameter bitPattern: The integer encoding of a `${Self}` instance. |
| @inlinable // FIXME(sil-serialize-all) |
| public init(bitPattern: UInt${bits}) { |
| self.init(Builtin.bitcast_Int${bits}_FPIEEE${bits}(bitPattern._value)) |
| } |
| |
| /// 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`. |
| @inlinable // FIXME(sil-serialize-all) |
| public var sign: FloatingPointSign { |
| let shift = ${Self}.significandBitCount + ${Self}.exponentBitCount |
| return FloatingPointSign(rawValue: Int(bitPattern &>> ${RawSignificand}(shift)))! |
| } |
| |
| @available(*, unavailable, renamed: "sign") |
| public var isSignMinus: Bool { Builtin.unreachable() } |
| |
| /// The raw encoding of the value's exponent field. |
| /// |
| /// This value is unadjusted by the type's exponent bias. |
| @inlinable // FIXME(sil-serialize-all) |
| public var exponentBitPattern: UInt { |
| return UInt(bitPattern &>> UInt${bits}(${Self}.significandBitCount)) & |
| ${Self}._infinityExponent |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public var significandBitPattern: ${RawSignificand} { |
| return ${RawSignificand}(bitPattern) & ${Self}._significandMask |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public init(sign: FloatingPointSign, |
| exponentBitPattern: UInt, |
| significandBitPattern: ${RawSignificand}) { |
| let signShift = ${Self}.significandBitCount + ${Self}.exponentBitCount |
| let sign = UInt${bits}(sign == .minus ? 1 : 0) |
| let exponent = UInt${bits}( |
| exponentBitPattern & ${Self}._infinityExponent) |
| let significand = UInt${bits}( |
| significandBitPattern & ${Self}._significandMask) |
| self.init(bitPattern: |
| sign &<< UInt${bits}(signShift) | |
| exponent &<< UInt${bits}(${Self}.significandBitCount) | |
| significand) |
| } |
| |
| /// 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 |
| @inlinable // FIXME(sil-serialize-all) |
| public var isCanonical: Bool { |
| return true |
| } |
| %else: |
| // Internal implementation details of x86 Float80 |
| @_fixed_layout // FIXME(sil-serialize-all) |
| @usableFromInline // FIXME(sil-serialize-all) |
| internal struct _Representation { |
| @usableFromInline // FIXME(sil-serialize-all) |
| internal var _storage: (UInt64, UInt16, /* pad */ UInt16, UInt16, UInt16) |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| internal var explicitSignificand: UInt64 { return _storage.0 } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| internal var signAndExponent: UInt16 { return _storage.1 } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| internal var sign: FloatingPointSign { |
| return FloatingPointSign(rawValue: Int(signAndExponent &>> 15))! |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| internal var exponentBitPattern: UInt { |
| return UInt(signAndExponent) & 0x7fff |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| internal init(explicitSignificand: UInt64, signAndExponent: UInt16) { |
| _storage = (explicitSignificand, signAndExponent, 0, 0, 0) |
| } |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| internal var _representation: _Representation { |
| return unsafeBitCast(self, to: _Representation.self) |
| } |
| |
| /// 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`. |
| @inlinable // FIXME(sil-serialize-all) |
| public var sign: FloatingPointSign { |
| return _representation.sign |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| internal static var _explicitBitMask: UInt64 { |
| @inline(__always) get { return 1 &<< 63 } |
| } |
| |
| /// The raw encoding of the value's exponent field. |
| /// |
| /// This value is unadjusted by the type's exponent bias. |
| @inlinable // FIXME(sil-serialize-all) |
| public var exponentBitPattern: UInt { |
| let provisional = _representation.exponentBitPattern |
| if provisional == 0 { |
| if _representation.explicitSignificand >= Float80._explicitBitMask { |
| // Pseudo-denormals have an exponent of 0 but the leading bit of the |
| // significand field is set. These are noncanonical encodings of the |
| // same significand with an exponent of 1. |
| return 1 |
| } |
| // Exponent is zero, leading bit of significand is clear, so this is |
| // a canonical zero or subnormal number. |
| return 0 |
| } |
| if _representation.explicitSignificand < Float80._explicitBitMask { |
| // If the exponent is not-zero but the leading bit of the significand |
| // is clear, then we have an invalid operand (unnormal, pseudo-inf, or |
| // pseudo-NaN). All of these are noncanonical encodings of NaN. |
| return Float80._infinityExponent |
| } |
| // We have a canonical number, so the provisional exponent is correct. |
| return provisional |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public var significandBitPattern: UInt64 { |
| if _representation.exponentBitPattern > 0 && |
| _representation.explicitSignificand < Float80._explicitBitMask { |
| // If the exponent is nonzero and the leading bit of the significand |
| // is clear, then we have an invalid operand (unnormal, pseudo-inf, or |
| // pseudo-NaN). All of these are noncanonical encodings of qNaN. |
| return _representation.explicitSignificand | Float80._quietNaNMask |
| } |
| // Otherwise we always get the "right" significand by simply clearing the |
| // integral bit. |
| return _representation.explicitSignificand & Float80._significandMask |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public init(sign: FloatingPointSign, |
| exponentBitPattern: UInt, |
| significandBitPattern: UInt64) { |
| let signBit = UInt16(sign == .minus ? 0x8000 : 0) |
| let exponent = UInt16(exponentBitPattern) |
| var significand = significandBitPattern |
| if exponent != 0 { significand |= Float80._explicitBitMask } |
| let rep = _Representation( |
| explicitSignificand: significand, signAndExponent: signBit|exponent) |
| self = unsafeBitCast(rep, to: Float80.self) |
| } |
| |
| /// 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 |
| @inlinable // FIXME(sil-serialize-all) |
| public var isCanonical: Bool { |
| if exponentBitPattern == 0 { |
| // If exponent field is zero, canonical numbers have the explicit |
| // significand bit clear. |
| return _representation.explicitSignificand < Float80._explicitBitMask |
| } |
| // If exponent is nonzero, canonical values have the explicit significand |
| // bit set. |
| return _representation.explicitSignificand >= Float80._explicitBitMask |
| } |
| %end |
| |
| /// 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 |
| @inlinable // FIXME(sil-serialize-all) |
| public static var infinity: ${Self} { |
| %if bits == 32: |
| return ${Self}(bitPattern: 0b0_11111111_00000000000000000000000) |
| %elif bits == 64: |
| return ${Self}( |
| bitPattern: 0b0_11111111111_0000000000000000000000000000000000000000000000000000) |
| %elif bits == 80: |
| let rep = _Representation( |
| explicitSignificand: ${Self}._explicitBitMask, |
| signAndExponent: 0b0_111111111111111) |
| return unsafeBitCast(rep, to: ${Self}.self) |
| %else: |
| return ${Self}(sign: .plus, |
| exponentBitPattern: _infinityExponent, |
| significandBitPattern: 0) |
| %end |
| } |
| |
| /// 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" |
| @inlinable // FIXME(sil-serialize-all) |
| public static var nan: ${Self} { |
| %if bits == 32: |
| return ${Self}(bitPattern: 0b0_11111111_10000000000000000000000) |
| %elif bits == 64: |
| return ${Self}( |
| bitPattern: 0b0_11111111111_1000000000000000000000000000000000000000000000000000) |
| %elif bits == 80: |
| let rep = _Representation( |
| explicitSignificand: ${Self}._explicitBitMask | ${Self}._quietNaNMask, |
| signAndExponent: 0b0_111111111111111) |
| return unsafeBitCast(rep, to: ${Self}.self) |
| %else: |
| return ${Self}(nan: 0, signaling: false) |
| %end |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public static var signalingNaN: ${Self} { |
| return ${Self}(nan: 0, signaling: true) |
| } |
| |
| @available(*, unavailable, renamed: "nan") |
| public static var quietNaN: ${Self} { Builtin.unreachable() } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public static var greatestFiniteMagnitude: ${Self} { |
| %if bits == 32: |
| return 0x1.fffffep127 |
| %elif bits == 64: |
| return 0x1.fffffffffffffp1023 |
| %elif bits == 80: |
| return 0x1.fffffffffffffffep16383 |
| %else: |
| return ${Self}(sign: .plus, |
| exponentBitPattern: _infinityExponent - 1, |
| significandBitPattern: _significandMask) |
| %end |
| } |
| |
| /// 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" |
| @inlinable // FIXME(sil-serialize-all) |
| public static var pi: ${Self} { |
| %if bits == 32: |
| // Note: this is not the correctly rounded (to nearest) value of pi, |
| // because pi would round *up* in Float precision, which can result |
| // in angles in the wrong quadrant if users aren't careful. This is |
| // not a problem for Double or Float80, as pi rounds down in both of |
| // those formats. |
| return 0x1.921fb4p1 |
| %elif bits == 64: |
| return 0x1.921fb54442d18p1 |
| %elif bits == 80: |
| return 0x1.921fb54442d1846ap1 |
| %end |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public var ulp: ${Self} { |
| %if bits != 80: |
| guard _fastPath(isFinite) else { return .nan } |
| if _fastPath(isNormal) { |
| let bitPattern_ = bitPattern & ${Self}.infinity.bitPattern |
| return ${Self}(bitPattern: bitPattern_) * 0x1p-${SignificandBitCount} |
| } |
| // On arm, flush subnormal values to 0. |
| return .leastNormalMagnitude * 0x1p-${SignificandBitCount} |
| %else: |
| guard _fastPath(isFinite) else { return .nan } |
| if exponentBitPattern > UInt(${Self}.significandBitCount) { |
| // self is large enough that self.ulp is normal, so we just compute its |
| // exponent and construct it with a significand of zero. |
| let ulpExponent = |
| exponentBitPattern - UInt(${Self}.significandBitCount) |
| return ${Self}(sign: .plus, |
| exponentBitPattern: ulpExponent, |
| significandBitPattern: 0) |
| } |
| if exponentBitPattern >= 1 { |
| // self is normal but ulp is subnormal. |
| let ulpShift = ${RawSignificand}(exponentBitPattern - 1) |
| return ${Self}(sign: .plus, |
| exponentBitPattern: 0, |
| significandBitPattern: 1 &<< ulpShift) |
| } |
| return ${Self}(sign: .plus, |
| exponentBitPattern: 0, |
| significandBitPattern: 1) |
| %end |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public static var leastNormalMagnitude: ${Self} { |
| %if bits == 32: |
| return 0x1p-126 |
| %elif bits == 64: |
| return 0x1p-1022 |
| %elif bits == 80: |
| return 0x1p-16382 |
| %else: |
| return ${Self}(sign: .plus, |
| exponentBitPattern: 1, |
| significandBitPattern: 0) |
| %end |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public static var leastNonzeroMagnitude: ${Self} { |
| #if arch(arm) |
| return leastNormalMagnitude |
| #else |
| %if bits == 32: |
| return 0x1p-149 |
| %elif bits == 64: |
| return 0x1p-1074 |
| %elif bits == 80: |
| return 0x1p-16445 |
| %else: |
| return ${Self}(sign: .plus, |
| exponentBitPattern: 0, |
| significandBitPattern: 1) |
| %end |
| #endif |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public static var ulpOfOne: ${Self} { |
| %if bits == 32: |
| return 0x1p-23 |
| %elif bits == 64: |
| return 0x1p-52 |
| %elif bits == 80: |
| return 0x1p-63 |
| %end |
| } |
| |
| /// 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 |
| @inlinable // FIXME(sil-serialize-all) |
| public var exponent: Int { |
| if !isFinite { return .max } |
| if isZero { return .min } |
| let provisional = Int(exponentBitPattern) - Int(${Self}._exponentBias) |
| if isNormal { return provisional } |
| let shift = |
| ${Self}.significandBitCount - |
| Int(significandBitPattern._binaryLogarithm()) |
| return provisional + 1 - shift |
| } |
| |
| /// 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 |
| @inlinable // FIXME(sil-serialize-all) |
| public var significand: ${Self} { |
| if isNaN { return self } |
| if isNormal { |
| return ${Self}(sign: .plus, |
| exponentBitPattern: ${Self}._exponentBias, |
| significandBitPattern: significandBitPattern) |
| } |
| if isSubnormal { |
| let shift = |
| ${RawSignificand}(${Self}.significandBitCount) - |
| significandBitPattern._binaryLogarithm() |
| return ${Self}(sign: .plus, |
| exponentBitPattern: ${Self}._exponentBias, |
| significandBitPattern: significandBitPattern &<< shift) |
| } |
| // zero or infinity. |
| return ${Self}(sign: .plus, |
| exponentBitPattern: exponentBitPattern, |
| significandBitPattern: 0) |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public init(sign: FloatingPointSign, exponent: Int, significand: ${Self}) { |
| var result = significand |
| if sign == .minus { result = -result } |
| if significand.isFinite && !significand.isZero { |
| var clamped = exponent |
| let leastNormalExponent = 1 - Int(${Self}._exponentBias) |
| let greatestFiniteExponent = Int(${Self}._exponentBias) |
| if clamped < leastNormalExponent { |
| clamped = max(clamped, 3*leastNormalExponent) |
| while clamped < leastNormalExponent { |
| result *= ${Self}.leastNormalMagnitude |
| clamped -= leastNormalExponent |
| } |
| } |
| else if clamped > greatestFiniteExponent { |
| clamped = min(clamped, 3*greatestFiniteExponent) |
| let step = ${Self}(sign: .plus, |
| exponentBitPattern: ${Self}._infinityExponent - 1, |
| significandBitPattern: 0) |
| while clamped > greatestFiniteExponent { |
| result *= step |
| clamped -= greatestFiniteExponent |
| } |
| } |
| let scale = ${Self}(sign: .plus, |
| exponentBitPattern: UInt(Int(${Self}._exponentBias) + clamped), |
| significandBitPattern: 0) |
| result = result * scale |
| } |
| self = result |
| } |
| |
| /// Creates a NaN ("not a number") value with the specified payload. |
| /// |
| /// NaN values compare not equal to every value, including themselves. Most |
| /// operations with a NaN operand produce a NaN result. Don't use the |
| /// equal-to operator (`==`) to test whether a value is NaN. Instead, use |
| /// the value's `isNaN` property. |
| /// |
| /// let x = ${Self}(nan: 0, signaling: false) |
| /// print(x == .nan) |
| /// // Prints "false" |
| /// print(x.isNaN) |
| /// // Prints "true" |
| /// |
| /// - Parameters: |
| /// - payload: The payload to use for the new NaN value. |
| /// - signaling: Pass `true` to create a signaling NaN or `false` to create |
| /// a quiet NaN. |
| @inlinable // FIXME(sil-serialize-all) |
| public init(nan payload: RawSignificand, signaling: Bool) { |
| // We use significandBitCount - 2 bits for NaN payload. |
| _precondition(payload < (${Self}._quietNaNMask &>> 1), |
| "NaN payload is not encodable.") |
| var significand = payload |
| significand |= ${Self}._quietNaNMask &>> (signaling ? 1 : 0) |
| self.init(sign: .plus, |
| exponentBitPattern: ${Self}._infinityExponent, |
| significandBitPattern: significand) |
| } |
| |
| /// 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`. |
| @inlinable // FIXME(sil-serialize-all) |
| public var nextUp: ${Self} { |
| %if bits != 80: |
| // Silence signaling NaNs, map -0 to +0. |
| let x = self + 0 |
| #if arch(arm) |
| // On arm, treat subnormal values as zero. |
| if _slowPath(x == 0) { return .leastNonzeroMagnitude } |
| if _slowPath(x == -.leastNonzeroMagnitude) { return -0.0 } |
| #endif |
| if _fastPath(x < .infinity) { |
| let increment = Int${bits}(bitPattern: x.bitPattern) &>> ${bits - 1} | 1 |
| let bitPattern_ = x.bitPattern &+ UInt${bits}(bitPattern: increment) |
| return ${Self}(bitPattern: bitPattern_) |
| } |
| return x |
| %else: |
| if isNaN { /* Silence signaling NaNs. */ return self + 0 } |
| if sign == .minus { |
| if significandBitPattern == 0 { |
| if exponentBitPattern == 0 { |
| return .leastNonzeroMagnitude |
| } |
| return ${Self}(sign: .minus, |
| exponentBitPattern: exponentBitPattern - 1, |
| significandBitPattern: ${Self}._significandMask) |
| } |
| return ${Self}(sign: .minus, |
| exponentBitPattern: exponentBitPattern, |
| significandBitPattern: significandBitPattern - 1) |
| } |
| if isInfinite { return self } |
| if significandBitPattern == ${Self}._significandMask { |
| return ${Self}(sign: .plus, |
| exponentBitPattern: exponentBitPattern + 1, |
| significandBitPattern: 0) |
| } |
| return ${Self}(sign: .plus, |
| exponentBitPattern: exponentBitPattern, |
| significandBitPattern: significandBitPattern + 1) |
| %end |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public mutating func round(_ rule: FloatingPointRoundingRule) { |
| switch rule { |
| case .toNearestOrAwayFromZero: |
| _value = Builtin.int_round_FPIEEE${bits}(_value) |
| case .toNearestOrEven: |
| _value = Builtin.int_rint_FPIEEE${bits}(_value) |
| case .towardZero: |
| _value = Builtin.int_trunc_FPIEEE${bits}(_value) |
| case .awayFromZero: |
| if sign == .minus { |
| _value = Builtin.int_floor_FPIEEE${bits}(_value) |
| } |
| else { |
| _value = Builtin.int_ceil_FPIEEE${bits}(_value) |
| } |
| case .up: |
| _value = Builtin.int_ceil_FPIEEE${bits}(_value) |
| case .down: |
| _value = Builtin.int_floor_FPIEEE${bits}(_value) |
| } |
| } |
| |
| /// 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 |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public mutating func negate() { |
| _value = Builtin.fneg_FPIEEE${bits}(self._value) |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public static func +=(_ lhs: inout ${Self}, _ rhs: ${Self}) { |
| lhs._value = Builtin.fadd_FPIEEE${bits}(lhs._value, rhs._value) |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public static func -=(_ lhs: inout ${Self}, _ rhs: ${Self}) { |
| lhs._value = Builtin.fsub_FPIEEE${bits}(lhs._value, rhs._value) |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public static func *=(_ lhs: inout ${Self}, _ rhs: ${Self}) { |
| lhs._value = Builtin.fmul_FPIEEE${bits}(lhs._value, rhs._value) |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public static func /=(_ lhs: inout ${Self}, _ rhs: ${Self}) { |
| lhs._value = Builtin.fdiv_FPIEEE${bits}(lhs._value, rhs._value) |
| } |
| |
| /// 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 |
| /// `formRemainder(dividingBy:)` method is always exact. |
| /// |
| /// - Parameter other: The value to use when dividing this value. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public mutating func formRemainder(dividingBy other: ${Self}) { |
| self = _stdlib_remainder${cFuncSuffix}(self, other) |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public mutating func formTruncatingRemainder(dividingBy other: ${Self}) { |
| _value = Builtin.frem_FPIEEE${bits}(self._value, other._value) |
| } |
| |
| /// Replaces this value with its square root, rounded to a representable |
| /// value. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public mutating func formSquareRoot( ) { |
| self = _stdlib_squareRoot${cFuncSuffix}(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. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public mutating func addProduct(_ lhs: ${Self}, _ rhs: ${Self}) { |
| _value = Builtin.int_fma_FPIEEE${bits}(lhs._value, rhs._value, _value) |
| } |
| |
| /// 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`. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public func isEqual(to other: ${Self}) -> Bool { |
| return Bool(Builtin.fcmp_oeq_FPIEEE${bits}(self._value, other._value)) |
| } |
| |
| /// 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`. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public func isLess(than other: ${Self}) -> Bool { |
| return Bool(Builtin.fcmp_olt_FPIEEE${bits}(self._value, other._value)) |
| } |
| |
| /// 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`. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public func isLessThanOrEqualTo(_ other: ${Self}) -> Bool { |
| return Bool(Builtin.fcmp_ole_FPIEEE${bits}(self._value, other._value)) |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public var isNormal: Bool { |
| return exponentBitPattern > 0 && isFinite |
| } |
| |
| /// A Boolean value indicating whether this instance is finite. |
| /// |
| /// All values other than NaN and infinity are considered finite, whether |
| /// normal or subnormal. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public var isFinite: Bool { |
| return exponentBitPattern < ${Self}._infinityExponent |
| } |
| |
| /// 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 |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public var isZero: Bool { |
| return exponentBitPattern == 0 && significandBitPattern == 0 |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public var isSubnormal: Bool { |
| return exponentBitPattern == 0 && significandBitPattern != 0 |
| } |
| |
| /// 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`. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public var isInfinite: Bool { |
| return !isFinite && significandBitPattern == 0 |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public var isNaN: Bool { |
| return !isFinite && significandBitPattern != 0 |
| } |
| |
| /// A Boolean value indicating whether the instance is a signaling NaN. |
| /// |
| /// Signaling NaNs typically raise the Invalid flag when used in general |
| /// computing operations. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public var isSignalingNaN: Bool { |
| return isNaN && (significandBitPattern & ${Self}._quietNaNMask) == 0 |
| } |
| |
| /// 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 |
| @inlinable // FIXME(sil-serialize-all) |
| public var binade: ${Self} { |
| %if bits != 80: |
| guard _fastPath(isFinite) else { return .nan } |
| #if !arch(arm) |
| if _slowPath(isSubnormal) { |
| let bitPattern_ = |
| (self * 0x1p${SignificandBitCount}).bitPattern |
| & (-${Self}.infinity).bitPattern |
| return ${Self}(bitPattern: bitPattern_) * 0x1p-${SignificandBitCount} |
| } |
| #endif |
| return ${Self}(bitPattern: bitPattern & (-${Self}.infinity).bitPattern) |
| %else: |
| guard _fastPath(isFinite) else { return .nan } |
| if exponentBitPattern != 0 { |
| return ${Self}(sign: sign, exponentBitPattern: exponentBitPattern, |
| significandBitPattern: 0) |
| } |
| if significandBitPattern == 0 { return self } |
| // For subnormals, we isolate the leading significand bit. |
| let index = significandBitPattern._binaryLogarithm() |
| return ${Self}(sign: sign, exponentBitPattern: 0, |
| significandBitPattern: 1 &<< index) |
| %end |
| } |
| |
| /// 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. |
| @inlinable // FIXME(sil-serialize-all) |
| public var significandWidth: Int { |
| let trailingZeroBits = significandBitPattern.trailingZeroBitCount |
| if isNormal { |
| guard significandBitPattern != 0 else { return 0 } |
| return ${Self}.significandBitCount &- trailingZeroBits |
| } |
| if isSubnormal { |
| let leadingZeroBits = significandBitPattern.leadingZeroBitCount |
| return ${RawSignificand}.bitWidth &- (trailingZeroBits &+ leadingZeroBits &+ 1) |
| } |
| return -1 |
| } |
| |
| /// Creates a new value from the given floating-point literal. |
| /// |
| /// Do not call this initializer directly. It is used by the compiler when |
| /// you create a new `${Self}` instance by using a floating-point literal. |
| /// Instead, create a new value by using a literal. |
| /// |
| /// In this example, the assignment to the `x` constant calls this |
| /// initializer behind the scenes. |
| /// |
| /// let x: ${Self} = 21.25 |
| /// // x == 21.25 |
| /// |
| /// - Parameter value: The new floating-point value. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public init(floatLiteral value: ${Self}) { |
| self = value |
| } |
| } |
| |
| extension ${Self} : _ExpressibleByBuiltinIntegerLiteral, ExpressibleByIntegerLiteral { |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public |
| init(_builtinIntegerLiteral value: Builtin.Int${builtinIntLiteralBits}){ |
| self = ${Self}(Builtin.itofp_with_overflow_Int${builtinIntLiteralBits}_FPIEEE${bits}(value)) |
| } |
| |
| /// Creates a new value from the given integer literal. |
| /// |
| /// Do not call this initializer directly. It is used by the compiler when |
| /// you create a new `${Self}` instance by using an integer literal. |
| /// Instead, create a new value by using a literal. |
| /// |
| /// In this example, the assignment to the `x` constant calls this |
| /// initializer behind the scenes. |
| /// |
| /// let x: ${Self} = 100 |
| /// // x == 100.0 |
| /// |
| /// - Parameter value: The new value. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public init(integerLiteral value: Int64) { |
| self = ${Self}(Builtin.sitofp_Int64_FPIEEE${bits}(value._value)) |
| } |
| } |
| |
| % if bits != 80: |
| #if !os(Windows) && (arch(i386) || arch(x86_64)) |
| % end |
| |
| % builtinFloatLiteralBits = 80 |
| extension ${Self} : _ExpressibleByBuiltinFloatLiteral { |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public |
| init(_builtinFloatLiteral value: Builtin.FPIEEE${builtinFloatLiteralBits}) { |
| % if bits == builtinFloatLiteralBits: |
| self = ${Self}(value) |
| % elif bits < builtinFloatLiteralBits: |
| self = ${Self}(Builtin.fptrunc_FPIEEE${builtinFloatLiteralBits}_FPIEEE${bits}(value)) |
| % else: |
| // FIXME: This is actually losing precision <rdar://problem/14073102>. |
| self = ${Self}(Builtin.fpext_FPIEEE${builtinFloatLiteralBits}_FPIEEE${bits}(value)) |
| % end |
| } |
| } |
| |
| % if bits != 80: |
| #else |
| |
| % builtinFloatLiteralBits = 64 |
| extension ${Self} : _ExpressibleByBuiltinFloatLiteral { |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public |
| init(_builtinFloatLiteral value: Builtin.FPIEEE${builtinFloatLiteralBits}) { |
| % if bits == builtinFloatLiteralBits: |
| self = ${Self}(value) |
| % elif bits < builtinFloatLiteralBits: |
| // FIXME: This can result in double rounding errors (SR-7124). |
| self = ${Self}(Builtin.fptrunc_FPIEEE${builtinFloatLiteralBits}_FPIEEE${bits}(value)) |
| % else: |
| // FIXME: This is actually losing precision <rdar://problem/14073102>. |
| self = ${Self}(Builtin.fpext_FPIEEE${builtinFloatLiteralBits}_FPIEEE${bits}(value)) |
| % end |
| } |
| } |
| |
| #endif |
| % end |
| |
| extension ${Self} : Hashable { |
| /// Hashes the essential components of this value by feeding them into the |
| /// given hasher. |
| /// |
| /// - Parameter hasher: The hasher to use when combining the components |
| /// of this instance. |
| @inlinable |
| public func hash(into hasher: inout Hasher) { |
| var v = self |
| if isZero { |
| // To satisfy the axiom that equality implies hash equality, we need to |
| // finesse the hash value of -0.0 to match +0.0. |
| v = 0 |
| } |
| %if bits == 80: |
| hasher.combine(v._representation.signAndExponent) |
| hasher.combine(v.significandBitPattern) |
| %else: |
| hasher.combine(v.bitPattern) |
| %end |
| } |
| |
| @inlinable |
| public func _rawHashValue(seed: (UInt64, UInt64)) -> Int { |
| // To satisfy the axiom that equality implies hash equality, we need to |
| // finesse the hash value of -0.0 to match +0.0. |
| let v = isZero ? 0 : self |
| %if bits == 80: |
| var hasher = Hasher(_seed: seed) |
| hasher.combine(v._representation.signAndExponent) |
| hasher.combine(v.significandBitPattern) |
| return hasher._finalize() |
| %elif bits == 64: |
| return Hasher._hash(seed: seed, v.bitPattern) |
| %elif bits == 32: |
| return Hasher._hash(seed: seed, bytes: UInt64(v.bitPattern), count: 4) |
| %end |
| } |
| } |
| |
| extension ${Self} { |
| /// The magnitude of this value. |
| /// |
| /// For any value `x`, `x.magnitude.sign` is `.plus`. If `x` is not NaN, |
| /// `x.magnitude` is the absolute value of `x`. |
| /// |
| /// The global `abs(_:)` function provides more familiar syntax when you need |
| /// to find an absolute value. In addition, because `abs(_:)` always returns |
| /// a value of the same type, even in a generic context, using the function |
| /// instead of the `magnitude` property is encouraged. |
| /// |
| /// let targetDistance: ${Self} = 5.25 |
| /// let throwDistance: ${Self} = 5.5 |
| /// |
| /// let margin = targetDistance - throwDistance |
| /// // margin == -0.25 |
| /// // margin.magnitude == 0.25 |
| /// |
| /// // Use 'abs(_:)' instead of 'magnitude' |
| /// print("Missed the target by \(abs(margin)) meters.") |
| /// // Prints "Missed the target by 0.25 meters." |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public var magnitude: ${Self} { |
| return ${Self}(Builtin.int_fabs_FPIEEE${bits}(_value)) |
| } |
| } |
| |
| extension ${Self} { |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public static prefix func - (x: ${Self}) -> ${Self} { |
| return ${Self}(Builtin.fneg_FPIEEE${bits}(x._value)) |
| } |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Explicit conversions between types. |
| //===----------------------------------------------------------------------===// |
| |
| // Construction from integers. |
| extension ${Self} { |
| |
| % for self_ty in all_integer_types(word_bits): |
| % That = self_ty.stdlib_name |
| % ThatBuiltinName = self_ty.builtin_name |
| % srcBits = self_ty.bits |
| % sign = 's' if self_ty.is_signed else 'u' |
| /// Creates the closest representable value to the given integer. |
| /// |
| /// - Parameter value: The integer to represent as a floating-point value. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public init(_ v: ${That}) { |
| _value = Builtin.${sign}itofp_${ThatBuiltinName}_FPIEEE${bits}(v._value) |
| } |
| |
| /// Creates a value that exactly represents the given integer. |
| /// |
| /// If the given integer is outside the representable range of this type or |
| /// can't be represented exactly, the result is `nil`. |
| /// |
| /// - Parameter value: The integer to represent as a floating-point value. |
| % if srcBits < SignificandBitCount: |
| @available(*, message: "Converting ${That} to ${Self} will always succeed.") |
| % end |
| @inlinable // FIXME(sil-serialize-all) |
| @inline(__always) |
| public init?(exactly value: ${That}) { |
| _value = Builtin.${sign}itofp_${ThatBuiltinName}_FPIEEE${bits}(value._value) |
| |
| % if srcBits >= SignificandBitCount: |
| guard let roundTrip = ${That}(exactly: self), |
| roundTrip == value else { |
| return nil |
| } |
| % end |
| } |
| % end # all_integer_types |
| } |
| |
| // Construction from other floating point numbers. |
| extension ${Self} { |
| % for src_type in all_floating_point_types(): |
| % srcBits = src_type.bits |
| % That = src_type.stdlib_name |
| |
| % if (srcBits == 80) and (bits != 80): |
| #if !os(Windows) && (arch(i386) || arch(x86_64)) |
| % end |
| |
| % if srcBits == bits: |
| /// Creates a new instance initialized to the given value. |
| /// |
| /// The value of `other` is represented exactly by the new instance. A NaN |
| /// passed as `other` results in another NaN, with a signaling NaN value |
| /// converted to quiet NaN. |
| % else: |
| /// Creates a new instance that approximates the given value. |
| /// |
| /// The value of `other` is rounded to a representable value, if necessary. |
| /// A NaN passed as `other` results in another NaN, with a signaling NaN |
| /// value converted to quiet NaN. |
| % end |
| /// |
| /// let x: ${That} = 21.25 |
| /// let y = ${Self}(x) |
| /// // y == 21.25 |
| /// |
| /// let z = ${Self}(${That}.nan) |
| /// // z.isNaN == true |
| /// |
| /// - Parameter other: The value to use for the new instance. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public init(_ other: ${That}) { |
| % if srcBits > bits: |
| _value = Builtin.fptrunc_FPIEEE${srcBits}_FPIEEE${bits}(other._value) |
| % elif srcBits < bits: |
| _value = Builtin.fpext_FPIEEE${srcBits}_FPIEEE${bits}(other._value) |
| % else: |
| _value = other._value |
| % end |
| } |
| |
| /// Creates a new instance initialized to the given value, if it can be |
| /// represented without rounding. |
| /// |
| /// If `other` can't be represented as an instance of `${Self}` without |
| /// rounding, the result of this initializer is `nil`. In particular, |
| /// passing NaN as `other` always results in `nil`. |
| /// |
| /// let x: ${That} = 21.25 |
| /// let y = ${Self}(exactly: x) |
| /// // y == Optional.some(21.25) |
| /// |
| /// let z = ${Self}(exactly: ${That}.nan) |
| /// // z == nil |
| /// |
| /// - Parameter other: The value to use for the new instance. |
| @inlinable // FIXME(sil-serialize-all) |
| @inline(__always) |
| public init?(exactly other: ${That}) { |
| self.init(other) |
| // Converting the infinity value is considered value preserving. |
| // In other cases, check that we can round-trip and get the same value. |
| // NaN always fails. |
| if ${That}(self) != other { |
| return nil |
| } |
| } |
| |
| % if (srcBits == 80) and (bits != 80): |
| #endif |
| % end |
| % end |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Standard Operator Table |
| //===----------------------------------------------------------------------===// |
| |
| // TODO: These should not be necessary, since they're already provided by |
| // <T: FloatingPoint>, but in practice they are currently needed to |
| // disambiguate overloads. We should find a way to remove them, either by |
| // tweaking the overload resolution rules, or by removing the other |
| // definitions in the standard lib, or both. |
| |
| extension ${Self} { |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public static func + (lhs: ${Self}, rhs: ${Self}) -> ${Self} { |
| var lhs = lhs |
| lhs += rhs |
| return lhs |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public static func - (lhs: ${Self}, rhs: ${Self}) -> ${Self} { |
| var lhs = lhs |
| lhs -= rhs |
| return lhs |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public static func * (lhs: ${Self}, rhs: ${Self}) -> ${Self} { |
| var lhs = lhs |
| lhs *= rhs |
| return lhs |
| } |
| |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public static func / (lhs: ${Self}, rhs: ${Self}) -> ${Self} { |
| var lhs = lhs |
| lhs /= rhs |
| return lhs |
| } |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Strideable Conformance |
| //===----------------------------------------------------------------------===// |
| |
| extension ${Self} : Strideable { |
| /// Returns the distance from this value to the specified value. |
| /// |
| /// For two values `x` and `y`, the result of `x.distance(to: y)` is equal to |
| /// `y - x`---a distance `d` such that `x.advanced(by: d)` approximates `y`. |
| /// For example: |
| /// |
| /// let x = 21.5 |
| /// let d = x.distance(to: 15.0) |
| /// // d == -6.5 |
| /// |
| /// print(x.advanced(by: d)) |
| /// // Prints "15.0" |
| /// |
| /// - Parameter other: A value to calculate the distance to. |
| /// - Returns: The distance between this value and `other`. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public func distance(to other: ${Self}) -> ${Self} { |
| return other - self |
| } |
| |
| /// Returns a new value advanced by the given distance. |
| /// |
| /// For two values `x` and `d`, the result of a `x.advanced(by: d)` is equal |
| /// to `x + d`---a new value `y` such that `x.distance(to: y)` approximates |
| /// `d`. For example: |
| /// |
| /// let x = 21.5 |
| /// let y = x.advanced(by: -6.5) |
| /// // y == 15.0 |
| /// |
| /// print(x.distance(to: y)) |
| /// // Prints "-6.5" |
| /// |
| /// - Parameter amount: The distance to advance this value. |
| /// - Returns: A new value that is `amount` added to this value. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public func advanced(by amount: ${Self}) -> ${Self} { |
| return self + amount |
| } |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Deprecated operators |
| //===----------------------------------------------------------------------===// |
| |
| @_transparent |
| @available(*, unavailable, message: "use += 1") |
| @discardableResult |
| public prefix func ++ (rhs: inout ${Self}) -> ${Self} { |
| fatalError("++ is not available") |
| } |
| @_transparent |
| @available(*, unavailable, message: "use -= 1") |
| @discardableResult |
| public prefix func -- (rhs: inout ${Self}) -> ${Self} { |
| fatalError("-- is not available") |
| } |
| @_transparent |
| @available(*, unavailable, message: "use += 1") |
| @discardableResult |
| public postfix func ++ (lhs: inout ${Self}) -> ${Self} { |
| fatalError("++ is not available") |
| } |
| @_transparent |
| @available(*, unavailable, message: "use -= 1") |
| @discardableResult |
| public postfix func -- (lhs: inout ${Self}) -> ${Self} { |
| fatalError("-- is not available") |
| } |
| |
| extension ${Self} { |
| @inlinable // FIXME(sil-serialize-all) |
| @available(swift, deprecated: 3.1, obsoleted: 4.0, message: "Please use the `abs(_:)` free function") |
| @_transparent |
| public static func abs(_ x: ${Self}) -> ${Self} { |
| return x.magnitude |
| } |
| } |
| |
| % if bits == 80: |
| #else |
| |
| ${SelfDocComment} |
| @_fixed_layout |
| @available(*, unavailable, message: "Float80 is only available on non-Windows x86 targets.") |
| public struct ${Self} { |
| /// Creates a value initialized to zero. |
| @inlinable // FIXME(sil-serialize-all) |
| @_transparent |
| public init() { |
| fatalError("${Self} is not available") |
| } |
| } |
| |
| #endif |
| % end |
| % end # for bits in all_floating_point_types |
| |
| @_transparent |
| @available(*, unavailable, |
| message: "For floating point numbers use truncatingRemainder instead") |
| public func % <T : BinaryFloatingPoint>(lhs: T, rhs: T) -> T { |
| fatalError("% is not available.") |
| } |
| |
| @_transparent |
| @available(*, unavailable, |
| message: "For floating point numbers use formTruncatingRemainder instead") |
| public func %= <T : BinaryFloatingPoint> (lhs: inout T, rhs: T) { |
| fatalError("%= is not available.") |
| } |
| |
| // ${'Local Variables'}: |
| // eval: (read-only-mode 1) |
| // End: |