Skip to content

[stdlib] Fix conversion from Float16 to unsigned integer types #36219

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 2 commits into from
Mar 2, 2021
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
22 changes: 18 additions & 4 deletions stdlib/public/core/IntegerTypes.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -1160,11 +1160,19 @@ public struct ${Self}
public init(_ source: ${FloatType}) {
_precondition(source.isFinite,
"${FloatType} value cannot be converted to ${Self} because it is either infinite or NaN")
% if not (FloatBits == 16 and bits >= 32): # Float16 is always in-range for 32- and 64-bit ints.
% if FloatBits == 16 and signed and bits >= 32:
// A Float16 value, if finite, is always in-range for 32- and 64-bit signed
// integer types.
% else:
_precondition(source > ${str(lower)}.0,
"${FloatType} value cannot be converted to ${Self} because the result would be less than ${Self}.min")
% if FloatBits == 16 and not signed and bits >= 16:
// A Float16 value, if greater than -1 and finite, is always in-range for
// 16-, 32-, and 64-bit unsigned integer types.
% else:
_precondition(source < ${str(upper)}.0,
"${FloatType} value cannot be converted to ${Self} because the result would be greater than ${Self}.max")
% end
% end
self._value = Builtin.fpto${u}i_FPIEEE${FloatBits}_${BuiltinName}(source._value)
}
Expand All @@ -1191,10 +1199,16 @@ public struct ${Self}
// The value passed as `source` must not be infinite, NaN, or exceed the
// bounds of the integer type; the result of `fptosi` or `fptoui` is
// undefined if it overflows.
% if not (FloatBits == 16 and bits >= 32): # Float16 is always in-range for 32- and 64-bit ints.
guard source > ${str(lower)}.0 && source < ${str(upper)}.0 else {
% else:
% if FloatBits == 16 and signed and bits >= 32:
// A Float16 value, if finite, is always in-range for 32- and 64-bit signed
// integer types.
guard source.isFinite else {
% elif FloatBits == 16 and not signed and bits >= 16:
// A Float16 value, if greater than -1 and finite, is always in-range for
// 16-, 32-, and 64-bit unsigned integer types.
guard source > ${str(lower)}.0 && source.isFinite else {
% else:
guard source > ${str(lower)}.0 && source < ${str(upper)}.0 else {
% end
return nil
}
Expand Down