-
Notifications
You must be signed in to change notification settings - Fork 10.5k
SE-0080 (3/5) - Failable initializers for Float->Int #3356
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
SE-0080 (3/5) - Failable initializers for Float->Int #3356
Conversation
a8c261a
to
25bcfad
Compare
if value.isFinite == false || value < ${str(lower)}.0 || value > ${str(upper)}.0 { | ||
return nil | ||
} | ||
self._value = Builtin.fpto${sign}i_FPIEEE${srcBits}_${BuiltinName}(value._value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see a check that value
is in-range, but I don't see any check that the value is preserved by the conversion. Am I simply missing something? What happens if value
is, e.g. 0.5?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gah, yeah that was an oversight. I meant to change the .isFinite
check to check if value % 1.0 == 0
and I somehow didn't notice the test failures last night.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, floating-point remainder is a very expensive operation. It is much cheaper to test if ${Src}(Self(value)) == value
. Or once/if SE-0113 lands, it would be better still to use value.rounded(.truncate) == value
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yeah I suppose that makes sense. I think in general I'm battling a perception that converting back/forth is more expensive than it really is.
168e271
to
30d18e7
Compare
Also it looks like one of the trapping cases isn't being handled correctly in the tests w/ is causing a failure. |
30d18e7
to
a449cc9
Compare
I think I covered everything. It turns gyb wasn't using the |
@swift-ci Please test. |
// Construction of integers from floating point numbers. | ||
% for srcBits in allFloatBits: | ||
% Src = floatName[srcBits] | ||
% (lower, upper) = getFtoIBounds(srcBits, int(bits), signed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend using argument labels in the getFtoIBounds
call for readability.
a449cc9
to
bb5d5d8
Compare
I think I got everything. Still running tests locally, but everything seems fine. |
Thank you! I will look closely tomorrow, but let's get a CI run early: @swift-ci Please test |
@ultramiraculous The CI has errors, would you mind taking a look? Also, I just wanted to remind you that we have a script, |
% else: | ||
|
||
% if testValue > selfMax: | ||
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}").crashOutputMatches(getTooLargeMessage()).code { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you wrap this line before .crashOutputMatches
?
Hah, I actually didn't know about |
190d046
to
c07bceb
Compare
Addressed the nits and moved some helpers into a python module. |
@swift-ci Please test |
return (1 << bits) - 1 | ||
|
||
def int_min(bits, signed): | ||
return -1 * int_max(bits, signed) - 1 if signed else 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To add some clarity, could you add parens around the first part of the expression? Otherwise it is not quite clear whether it's:
(-1 * int_max(bits, signed) - 1) if signed else 0
or
-1 * int_max(bits, signed) - (1 if signed else 0)
FWIW: the build failure is unrelated (it's PlaygroundLogger). |
828713e
to
b11d14a
Compare
Got the nits! |
b11d14a
to
4caf64a
Compare
@gribozavr I just dusted off the remainder of this proposal and it's like 50 lines of code, some of which depend on this PR. Any chance you could look at this :P |
Given that SE-0080 is purely additive, it is possible that we can take this. However, @tkremenek is the ultimate gatekeeper on that decision after technical review and approval has been done. |
I would be strongly supportive of taking an implementation of SE-0080 if we feel comfortable with the implementation and it landed very soon. |
#if !os(Windows) && (arch(i386) || arch(x86_64)) | ||
% end | ||
|
||
/// Creates a ${Self} whose value is `value` rounded towards zero. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you restore the original doc comment?
/// Creates a new instance by rounding the given floating-point value toward
/// zero.
///
/// - Parameter other: A floating-point value. When `other` is rounded toward
/// zero, the result must be within the range `${Self}.min...${Self}.max`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't notice it changed in the mean time. Added back.
Sorry for a delayed review! The changes LGTM! @swift-ci Please test |
@swift-ci Please test OS X platform |
What's in this pull request?
Breaking out from #2742. Adds init?(exactly:) initializers for integer types from float types.
Resolved bug number: (SR-1491)
Before merging this pull request to apple/swift repository:
Triggering Swift CI
The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:
Smoke Testing
Validation Testing
Lint Testing
Note: Only members of the Apple organization can trigger swift-ci.