Skip to content

[stdlib] Add another fast path for generic floating-point conversion #33826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 10, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 36 additions & 9 deletions stdlib/public/core/FloatingPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1890,21 +1890,48 @@ extension BinaryFloatingPoint {
/// - Parameter value: A floating-point value to be converted.
@inlinable
public init<Source: BinaryFloatingPoint>(_ value: Source) {
// If two IEEE 754 binary interchange formats share the same exponent bit
// count and significand bit count, then they must share the same encoding
// for finite and infinite values.
switch (Source.exponentBitCount, Source.significandBitCount) {
#if !os(macOS) && !(os(iOS) && targetEnvironment(macCatalyst))
if #available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
if case let value_ as Float16 = value {
self = Self(Float(value_))
return
case (5, 10):
guard #available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) else {
self = Self._convert(from: value).value
break
}
}
let value_ = value as? Float16 ?? Float16(
sign: value.sign,
exponentBitPattern:
UInt(truncatingIfNeeded: value.exponentBitPattern),
significandBitPattern:
UInt16(truncatingIfNeeded: value.significandBitPattern))
self = Self(Float(value_))
#endif
switch value {
case let value_ as Float:
case (8, 23):
let value_ = value as? Float ?? Float(
sign: value.sign,
exponentBitPattern:
UInt(truncatingIfNeeded: value.exponentBitPattern),
significandBitPattern:
UInt32(truncatingIfNeeded: value.significandBitPattern))
self = Self(value_)
case let value_ as Double:
case (11, 52):
let value_ = value as? Double ?? Double(
sign: value.sign,
exponentBitPattern:
UInt(truncatingIfNeeded: value.exponentBitPattern),
significandBitPattern:
UInt64(truncatingIfNeeded: value.significandBitPattern))
self = Self(value_)
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
case let value_ as Float80:
case (15, 63):
let value_ = value as? Float80 ?? Float80(
sign: value.sign,
exponentBitPattern:
UInt(truncatingIfNeeded: value.exponentBitPattern),
significandBitPattern:
UInt64(truncatingIfNeeded: value.significandBitPattern))
self = Self(value_)
#endif
default:
Expand Down