Protocolswift 6.0.1Swift
FloatingPoint
A floating-point numeric type.
protocol FloatingPoint : Hashable, SignedNumeric, Strideable where Self == Self.Magnitude
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. 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.
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 }
print(tempsCelsius)
// Prints "[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 }
print(tempsFahrenheit)
// Prints "[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, +) / 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, +) / 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."
Supertypes
protocol AdditiveArithmetic
A type with values that support addition and subtraction.
protocol Comparable
A type that can be compared using the relational operators
<
,<=
,>=
, and>
.protocol Equatable
A type that can be compared for value equality.
protocol ExpressibleByIntegerLiteral
A type that can be initialized with an integer literal.
protocol Hashable
A type that can be hashed into a
Hasher
to produce an integer hash value.protocol Numeric
A type with values that support multiplication.
protocol SignedNumeric
A numeric type with a negation operation.
protocol Strideable<Stride>
A type representing continuous, one-dimensional values that can be offset and measured.
Requirements
Type members
associatedtype Exponent
A type that can represent any written exponent.
init(Int
) Creates a new value, rounded to the closest possible representation.
init<Source>(Source
) Creates a new value, rounded to the closest possible representation.
init?<Source>(exactly: Source
) Creates a new value, if the given integer can be represented exactly.
init(sign: FloatingPointSign, exponent: Self.Exponent, significand: Self
) Creates a new value from the given sign, exponent, and significand.
init(signOf: Self, magnitudeOf: Self
) Creates a new floating-point value using the sign of one value and the magnitude of another.
static var greatestFiniteMagnitude: Self
The greatest finite number representable by this type.
static var infinity: Self
Positive infinity.
static var leastNonzeroMagnitude: Self
The least positive number.
static var leastNormalMagnitude: Self
The least positive normal number.
static var nan: Self
A quiet NaN (“not a number”).
static var pi: Self
The mathematical constant pi (π), approximately equal to 3.14159.
static var radix: Int
The radix, or base of exponentiation, for a floating-point type.
static var signalingNaN: Self
A signaling NaN (“not a number”).
static var ulpOfOne: Self
The unit in the last place of 1.0.
static func maximum(Self, Self
) -> Self Returns the greater of the two given values.
static func maximumMagnitude(Self, Self
) -> Self Returns the value with greater magnitude.
static func minimum(Self, Self
) -> Self Returns the lesser of the two given values.
static func minimumMagnitude(Self, Self
) -> Self Returns the value with lesser magnitude.
static func * (lhs: Self, rhs: Self
) -> Self Multiplies two values and produces their product, rounding to a representable value.
static func *= (lhs: inout Self, rhs: Self
) Multiplies two values and stores the result in the left-hand-side variable, rounding to a representable value.
static func + (lhs: Self, rhs: Self
) -> Self Adds two values and produces their sum, rounded to a representable value.
static func += (lhs: inout Self, rhs: Self
) Adds two values and stores the result in the left-hand-side variable, rounded to a representable value.
static func - (operand: Self
) -> Self Calculates the additive inverse of a value.
static func - (lhs: Self, rhs: Self
) -> Self Subtracts one value from another and produces their difference, rounded to a representable value.
static func -= (lhs: inout Self, rhs: Self
) Subtracts the second value from the first and stores the difference in the left-hand-side variable, rounding to a representable value.
static func / (lhs: Self, rhs: Self
) -> Self Returns the quotient of dividing the first value by the second, rounded to a representable value.
static func /= (lhs: inout Self, rhs: Self
) Divides the first value by the second and stores the quotient in the left-hand-side variable, rounding to a representable value.
Instance members
var exponent: Self.Exponent
The exponent of the floating-point value.
var floatingPointClass: FloatingPointClassification
The classification of this value.
var isCanonical: Bool
A Boolean value indicating whether the instance’s representation is in its canonical form.
var isFinite: Bool
A Boolean value indicating whether this instance is finite.
var isInfinite: Bool
A Boolean value indicating whether the instance is infinite.
var isNaN: Bool
A Boolean value indicating whether the instance is NaN (“not a number”).
var isNormal: Bool
A Boolean value indicating whether this instance is normal.
var isSignalingNaN: Bool
A Boolean value indicating whether the instance is a signaling NaN.
var isSubnormal: Bool
A Boolean value indicating whether the instance is subnormal.
var isZero: Bool
A Boolean value indicating whether the instance is equal to zero.
var nextDown: Self
The greatest representable value that compares less than this value.
var nextUp: Self
The least representable value that compares greater than this value.
var sign: FloatingPointSign
The sign of the floating-point value.
var significand: Self
The significand of the floating-point value.
var ulp: Self
The unit in the last place of this value.
func addProduct(Self, Self
) Adds the product of the two given values to this value in place, computed without intermediate rounding.
func addingProduct(Self, Self
) -> Self Returns the result of adding the product of the two given values to this value, computed without intermediate rounding.
func formRemainder(dividingBy: Self
) Replaces this value with the remainder of itself divided by the given value.
func formSquareRoot(
) Replaces this value with its square root, rounded to a representable value.
func formTruncatingRemainder(dividingBy: Self
) Replaces this value with the remainder of itself divided by the given value using truncating division.
func isEqual(to: Self
) -> Bool Returns a Boolean value indicating whether this instance is equal to the given value.
func isLess(than: Self
) -> Bool Returns a Boolean value indicating whether this instance is less than the given value.
func isLessThanOrEqualTo(Self
) -> Bool Returns a Boolean value indicating whether this instance is less than or equal to the given value.
func isTotallyOrdered(belowOrEqualTo: Self
) -> Bool Returns a Boolean value indicating whether this instance should precede or tie positions with the given value in an ascending sort.
func negate(
) Replaces this value with its additive inverse.
func remainder(dividingBy: Self
) -> Self Returns the remainder of this value divided by the given value.
func round(FloatingPointRoundingRule
) Rounds the value to an integral value using the specified rounding rule.
func rounded(FloatingPointRoundingRule
) -> Self Returns this value rounded to an integral value using the specified rounding rule.
func squareRoot(
) -> Self Returns the square root of the value, rounded to a representable value.
func truncatingRemainder(dividingBy: Self
) -> Self Returns the remainder of this value divided by the given value using truncating division.
Citizens in Swift
Type members
static var ulpOfOne: Self
static func maximum(Self, Self
) -> Self static func maximumMagnitude(Self, Self
) -> Self static func minimum(Self, Self
) -> Self static func minimumMagnitude(Self, Self
) -> Self static func < (lhs: Self, rhs: Self
) -> Bool static func <= (lhs: Self, rhs: Self
) -> Bool static func == (lhs: Self, rhs: Self
) -> Bool static func > (lhs: Self, rhs: Self
) -> Bool static func >= (lhs: Self, rhs: Self
) -> Bool
Instance members
var floatingPointClass: FloatingPointClassification
var nextDown: Self
func addingProduct(Self, Self
) -> Self func remainder(dividingBy: Self
) -> Self func round(
) func rounded(
) -> Self func rounded(FloatingPointRoundingRule
) -> Self func squareRoot(
) -> Self func truncatingRemainder(dividingBy: Self
) -> Self
Subtypes
protocol BinaryFloatingPoint
A radix-2 (binary) floating-point type.
Extension in RealModule
Subtypes
protocol Real
A type that models the real numbers.