Skip to content

Commit d4300dd

Browse files
authored
[stdlib] Fix conversion from Float16 to unsigned integer types (#36219)
* [stdlib] Fix conversion from Float16 to unsigned integer types * [stdlib] Tighten up concrete Float16-to-integer conversions
1 parent d26b1f0 commit d4300dd

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

stdlib/public/core/IntegerTypes.swift.gyb

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,11 +1160,19 @@ public struct ${Self}
11601160
public init(_ source: ${FloatType}) {
11611161
_precondition(source.isFinite,
11621162
"${FloatType} value cannot be converted to ${Self} because it is either infinite or NaN")
1163-
% if not (FloatBits == 16 and bits >= 32): # Float16 is always in-range for 32- and 64-bit ints.
1163+
% if FloatBits == 16 and signed and bits >= 32:
1164+
// A Float16 value, if finite, is always in-range for 32- and 64-bit signed
1165+
// integer types.
1166+
% else:
11641167
_precondition(source > ${str(lower)}.0,
11651168
"${FloatType} value cannot be converted to ${Self} because the result would be less than ${Self}.min")
1169+
% if FloatBits == 16 and not signed and bits >= 16:
1170+
// A Float16 value, if greater than -1 and finite, is always in-range for
1171+
// 16-, 32-, and 64-bit unsigned integer types.
1172+
% else:
11661173
_precondition(source < ${str(upper)}.0,
11671174
"${FloatType} value cannot be converted to ${Self} because the result would be greater than ${Self}.max")
1175+
% end
11681176
% end
11691177
self._value = Builtin.fpto${u}i_FPIEEE${FloatBits}_${BuiltinName}(source._value)
11701178
}
@@ -1191,10 +1199,16 @@ public struct ${Self}
11911199
// The value passed as `source` must not be infinite, NaN, or exceed the
11921200
// bounds of the integer type; the result of `fptosi` or `fptoui` is
11931201
// undefined if it overflows.
1194-
% if not (FloatBits == 16 and bits >= 32): # Float16 is always in-range for 32- and 64-bit ints.
1195-
guard source > ${str(lower)}.0 && source < ${str(upper)}.0 else {
1196-
% else:
1202+
% if FloatBits == 16 and signed and bits >= 32:
1203+
// A Float16 value, if finite, is always in-range for 32- and 64-bit signed
1204+
// integer types.
11971205
guard source.isFinite else {
1206+
% elif FloatBits == 16 and not signed and bits >= 16:
1207+
// A Float16 value, if greater than -1 and finite, is always in-range for
1208+
// 16-, 32-, and 64-bit unsigned integer types.
1209+
guard source > ${str(lower)}.0 && source.isFinite else {
1210+
% else:
1211+
guard source > ${str(lower)}.0 && source < ${str(upper)}.0 else {
11981212
% end
11991213
return nil
12001214
}

0 commit comments

Comments
 (0)