-
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
Change abs() to return unsigned integers #1017
Conversation
…d-integers/1747/5
Another alternative: return an |
Do any languages with a signed-unsigned dichotomy actually do this? Java and C++ both do Self -> Self (Java only recently got support for dealing with unsigned values, though). |
Ada's standard library complex numbers return a real value from the abs function. -- the interface definition
function "abs" (Right : Complex) return Real'Base;
function "abs" (Right : Imaginary) return Real'Base; Then there are the vectors and matrices (http://www.adaic.org/resources/add_content/standards/05rat/html/Rat-7-6.html)
Note: the |
Another alternative: insert debug checks similar to overflow checks to prevent |
Interestingly, Firefox does not use the abs function of the C standard library, but a custom one that returns unsigned integers: These links also explain why C returns signed integers by default (because when the result is used in a formula, other values are automatically promoted to unsigned). This is a problem that Rust does not have. |
@gankro: Java not only has incomplete support for working with unsigned integers. As of Java 8 there is no notion of (un)signedness in the type system, and the defined operations on java.lang.Long/java.lang.Integer don't even fully support the usual arithmetics. C/C++ has the problem of implicit coercions, as pitdicker already pointed out. This change would make the result strictly more correct, also the type would give a strong indication of the possible return values. Of course this would require explicit casts in those cases where calculations should continue with signed values, but this serves to make the problematic case (min_value) more obvious. I can also imagine it would help debugging if the failure comes from the cast operation instead of the abs function. |
👍 I have seen some of the problems |
@pnkfelix @nikomatsakis Thoughts? |
👍 I've been bitten by |
Regarding the RFC itself, this seems ... incomplete. In particular, support for an trait SignedInt {
type UnsignedVariant;
fn abs(&self) -> Self::UnsignedVariant;
...
} right? |
@aturon my gut reaction is that I usually expect operations like But it seems like a fair number of people here are in favor of this change, and it sounds like the real world bugs here may be relevant. @nikomatsakis when you say "pretty easy to workaround", I wonder if you are expecting people to use Anyway, I do not object to this RFC, assuming the oversight noted above is addressed in some way. |
I think that we should make sure whether we want the unsigned result or not. I don't quite remember, but in most cases the results have been more likely to be casted to signed. In that case, the occurrence of I'm more fond of doing a runtime check and panicking, or even making |
@barosl if you look at http://internals.rust-lang.org/t/pre-rfc-change-abs-to-return-unsigned-integers/1747/5?u=ker you can see that there's not a single case in rustc that casts it back to signed (except for the I could check out the most popular crates and make the same analysis on them...
could this be combined? by defining a trait for the |
I've always thought that @pnkfelix |
The team discussed this in the weekly meeting last night: https://github.com/rust-lang/meeting-minutes/blob/master/weekly-meetings/2015-04-07.md#change-abs-to-return-unsigned There was opposition to changing the type signature of (I did suggest the more conservative option of treating It seems like this is not going to be accepted, and instead one should write |
It's true that we talked about this in the meeting, but I think we didn't give it the consideration it deserves. It feels to me like |
@nikomatsakis but then at that point we should probably offer both variants (one that returns a signed int that may panic when given the minimum value, and another that returns an unsigned int that is guaranteed not to panic), right? |
more like trait SignedInt {
fn abs(&self) -> <Self as ToUnsigned>::Target where Self: ToUnsigned {
let x = if self < 0 { -self } else { self };
ToUnsigned::to_unsigned(x)
}
...
} |
I can understand not wanting to change the return type of If that is not possible at this stage, I think it is very important that |
I think this is a very good idea. This statically guarantees no overflow vs. the debug assert solution that is SOMETIMES triggered by tests, but sometimes not covered. |
I believe that |
@theemathas this is simply incorrect. This runs successfully: use std::i8;
fn main() {
for (i, u) in (i8::MIN..1).rev().zip(0u8..) {
assert_eq!(u, i.abs() as u8);
}
} |
+1 to this change (and fix bug/oversight of `INT_MIN.abs() == INT_MIN`).
It's never late to fix bug, we're still pre-1.0 final. (Maybe the core team
made a wrong decision here.)
|
@gankro if we adopt the potential-panic-on-int-min semantics for |
@theemathas No, plans changed. |
So, while mistakenly looking for this thread on the rust repo, I did find these old links:
which is mostly a historical curiosity. My immediate question is this: Should be mark the Or should we just make a decision, period? (Update: Or should we add stable |
@pnkfelix I have my doubts about adding a seperate |
@pitdicker well, fixed-size integers are the only ones vulnerable to this discontinuity. One can make the same argument but about types: why should integer types change to "unsigned" variances but not floating-point or bigint? My current feeling is that
this implies that it may be panic on overflow. I have no objection to adding |
Previous weekend brson was kind enough to test what impact this change would have on the crates on crates.io.
For Conclusion: I think the impact is small, but could be worth it especially when a crate fails to build. |
I think there should definitely be an If, however, the current return type of |
This RFC unfortunately did not reach consensus before the 1.0 release, and these methods have now been stabilized. The Thanks regardless for the RFC @pitdicker! |
To propose the addition of a |
I'd recommend an RFC for that API. The libraries subteam hasn't quite settled on what concretely needs an RFC and what doesn't, but I suspect that the guidelines would recommend an RFC for a method like |
(I would personally accept a PR for it; but that's just me) |
Change the function
abs()
to return unsigned integers, instead of signed integers as it does today.See http://internals.rust-lang.org/t/pre-rfc-change-abs-to-return-unsigned-integers/1747/5