Skip to content

Commit f40fd36

Browse files
committed
[stdlib] Add another fast path for generic floating-point conversion
1 parent 8c2e423 commit f40fd36

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

stdlib/public/core/FloatingPoint.swift

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,62 @@ extension BinaryFloatingPoint {
19081908
self = Self(value_)
19091909
#endif
19101910
default:
1911+
if value.isFinite {
1912+
// According to IEEE 754:
1913+
// - The set of finite floating-point numbers representable within a
1914+
// particular format is determined by: the radix (b), the precision
1915+
// (p, the number of digits in the significand), and the maximum and
1916+
// minimum exponent (emax and emin, respectively, where
1917+
// emin = 1 - emax).
1918+
// - In a binary interchange format, each floating-point number has only
1919+
// one encoding.
1920+
//
1921+
// If two binary interchange formats have the same exponent bit count
1922+
// (w) and significand bit count (p - 1), then they must share the same
1923+
// encoding for finite values.
1924+
switch (Source.exponentBitCount, Source.significandBitCount) {
1925+
#if !os(macOS) && !(os(iOS) && targetEnvironment(macCatalyst))
1926+
case (5, 10):
1927+
if #available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
1928+
let value_ = Float16(
1929+
sign: value.sign,
1930+
exponentBitPattern: Float16.RawExponent(value.exponentBitPattern),
1931+
significandBitPattern:
1932+
Float16.RawSignificand(value.significandBitPattern))
1933+
self = Self(Float(value_))
1934+
return
1935+
}
1936+
#endif
1937+
case (8, 23):
1938+
let value_ = Float(
1939+
sign: value.sign,
1940+
exponentBitPattern: Float.RawExponent(value.exponentBitPattern),
1941+
significandBitPattern:
1942+
Float.RawSignificand(value.significandBitPattern))
1943+
self = Self(value_)
1944+
return
1945+
case (11, 52):
1946+
let value_ = Double(
1947+
sign: value.sign,
1948+
exponentBitPattern: Double.RawExponent(value.exponentBitPattern),
1949+
significandBitPattern:
1950+
Double.RawSignificand(value.significandBitPattern))
1951+
self = Self(value_)
1952+
return
1953+
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
1954+
case (15, 63):
1955+
let value_ = Float80(
1956+
sign: value.sign,
1957+
exponentBitPattern: Float80.RawExponent(value.exponentBitPattern),
1958+
significandBitPattern:
1959+
Float80.RawSignificand(value.significandBitPattern))
1960+
self = Self(value_)
1961+
return
1962+
#endif
1963+
default:
1964+
break
1965+
}
1966+
}
19111967
self = Self._convert(from: value).value
19121968
}
19131969
}

0 commit comments

Comments
 (0)