Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upChange abs() to return unsigned integers #1017
Conversation
pitdicker
changed the title
http://internals.rust-lang.org/t/pre-rfc-change-abs-to-return-unsigned-i...
Change abs() to return unsigned integers
Mar 26, 2015
This comment has been minimized.
This comment has been minimized.
|
Another alternative: return an |
This comment has been minimized.
This comment has been minimized.
|
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). |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
Another alternative: insert debug checks similar to overflow checks to prevent |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
@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. |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@pnkfelix @nikomatsakis Thoughts? |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
Regarding the RFC itself, this seems ... incomplete. In particular, support for an trait SignedInt {
type UnsignedVariant;
fn abs(&self) -> Self::UnsignedVariant;
...
}right? |
This comment has been minimized.
This comment has been minimized.
|
@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. |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
@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 |
This comment has been minimized.
This comment has been minimized.
|
I've always thought that @pnkfelix |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
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 |
This comment has been minimized.
This comment has been minimized.
|
@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? |
This comment has been minimized.
This comment has been minimized.
bombless
commented
Apr 9, 2015
|
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)
}
...
} |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
nrc
assigned
brson
Apr 9, 2015
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
theemathas
commented
Apr 10, 2015
|
I believe that |
This comment has been minimized.
This comment has been minimized.
|
@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);
}
} |
This comment has been minimized.
This comment has been minimized.
|
+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.)
|
This comment has been minimized.
This comment has been minimized.
|
@Gankro if we adopt the potential-panic-on-int-min semantics for |
This comment has been minimized.
This comment has been minimized.
theemathas
commented
Apr 10, 2015
This comment has been minimized.
This comment has been minimized.
|
@theemathas No, plans changed. |
This comment has been minimized.
This comment has been minimized.
|
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
referenced this pull request
Apr 17, 2015
Merged
Check for overflow in arithmetic negation #24500
This comment has been minimized.
This comment has been minimized.
|
@pnkfelix I have my doubts about adding a seperate |
This comment has been minimized.
This comment has been minimized.
|
@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 |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
I think there should definitely be an If, however, the current return type of |
pnkfelix
referenced this pull request
May 13, 2015
Closed
std::i32::MIN.abs() results in panicked at 'arithmetic operation overflowed' #25378
alexcrichton
added
the
T-libs
label
May 18, 2015
This comment has been minimized.
This comment has been minimized.
|
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! |
alexcrichton
closed this
Jun 2, 2015
This comment has been minimized.
This comment has been minimized.
|
To propose the addition of a |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
(I would personally accept a PR for it; but that's just me) |
pitdicker commentedMar 26, 2015
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