-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add unsafe number ops #7226
Add unsafe number ops #7226
Conversation
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.
Great work! The only thing I'm not sure about is the to_unsafe_...
name. It's not really unsafe, converting -1
to UInt8
gives 255, the program wont' crash or behave incorrectly. That said, I can't come up with a better name, and the unsafe
there probably means you'll want to double check whether you really want to use those methods instead of the stronger variants. So 👍
I agree with @asterite there is nothing unsafe in those conversions. It's unchecked for over/underflow, or it's maybe wrapping, as in "be careful, it may not be the value you meant", but it's never unsafe as in "be careful, this can segfault". Maybe just |
@ysbaddaden I think |
@asterite |
|
@RX14 but they're not, truncating is way different then overflowing:
with truncating behavior I'd expect that |
@Sija you're cutting off the top bits when you cast to a smaller type. It's exactly truncation. |
There are already |
@RX14 What about when the size is kept? Converting Int32 to UInt32 doesn't truncate. It simply changes the interpretation of the byte values. This re-interpretation is similar to Maybe |
@RX14 so it seems that's a semantic issue as well, for me the result of |
Got an idea, what about appending a exclamation mark: |
Maybe the bang alternative is not bad, Since it's not a method I would expect to be used that much by the user, using a more verbose name should be fine. |
@bcardiff I liked your explanation. Now I think keeping unsafe in the names is fine. Plus you would most likely use these methods when interfacing with C. |
To throw another option into the ring: I don't follow why |
@asterite it won't be used just when interacting with C but anytime you must implement a binary protocol where overflow is expected: random number generators, HTTP/2 HPACK headers (huffman compression), probably in decoding DWARF sections, ... I'm fine with a longer name, but would prefer a rust-like |
I would not got with It's true that wrapping is more explicit, but the behavior was not settle for example in BigInt. Calling The wrapping works fine in integer but for floats the semantic it's truncation actually. |
@straight-shoota regarding
I meant for consistency. |
I'm with with |
I would like some more final comments or proposals in the light of my last comments regarding why We could have a method for truncation as public API and still have a |
I think Then, there's nothing I also thought about I'm thinking |
Ok so the api can be |
c1fdc8f
to
fbcc327
Compare
ready |
@bcardiff Have you seen #7226 (comment) and #7226 (comment) ? That's minor style improvement, still it reads better :) |
fbcc327
to
14d3175
Compare
Sorry, @j8r done! I would like one more core team member review before merging and go to the next partial PR for overflow. |
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.
Just a few minor improvements.
cast will be used for .as(T) expressions only.
new! initializers use #to_*! to avoid overflow if the value is out of range of the target type
Adding noted for future raising of OverflowError
Add BigDecimal#to_big_i, BigDecimal#to_big_u Note: BigRational does not have to_i / to_u methods
14d3175
to
1edf4a8
Compare
This PR adds some new methods to be able to keep current wrapping/unsafe behaviour once the overflow is activated.
New methods/constructs:
value.to_iX!
/value.to_uX!
/value.to_fX!
value.unsafe_to_iX
/value.unsafe_to_uX
/value.unsafe_to_fX
Int32.new!(value)
.Int32.unsafe_new(value)
Int#&**
is also added, andInt#**
was refactored to avoid possible overflow in last iteration.It prepares some new primitives to be able to have cleaner compiler code in the future. That is, drop the
:cast
internal in favor of:convert
and:unchecked_convert
to reflect better the nature of to_X methods.:unsafe_convert
This new methods should be used to be ready for upcoming breaking changes.