Skip to content
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

Interaction of addition and checked conversion #15489

Closed
Keno opened this issue Mar 14, 2016 · 12 comments
Closed

Interaction of addition and checked conversion #15489

Keno opened this issue Mar 14, 2016 · 12 comments
Assignees
Milestone

Comments

@Keno
Copy link
Member

Keno commented Mar 14, 2016

Consider for example:

julia> 0x00007ffea27edaa0+(-40)
ERROR: InexactError()
in +(::UInt64, ::Int64) at ./promotion.jl:172
in eval(::Module, ::Any) at ./boot.jl:267

julia> 0x00007ffea27edaa0-40
0x00007ffea27eda78

It is understandable why this happens, but the behavior is annoying. At least for integers of the same size, this addition is unambiguous.

@eschnett
Copy link
Contributor

If UInt has wrap-around semantics, then one can argue that converting any Int to UInt should succeed.

@vtjnash
Copy link
Member

vtjnash commented Mar 14, 2016

At least for integers of the same size, this addition is unambiguous

it could be non-trivial, since the result would require a Int65 to hold the intermediate result (or perhaps checked arithmetic as well)

@Keno
Copy link
Member Author

Keno commented Mar 14, 2016

We generally have allowed anything that makes sense on a value-preserving level. If integers are the same size then as long as the result is an unsigned integer, either interpretation (subtraction of 40, or addition of reinterpret(UInt,-40) yields the same result). To @vtjnash's point, I think that's a different issue, because we do allow overflow just fine.

@StefanKarpinski
Copy link
Member

We should probably make this work but it can't work by normal promotion/conversion, which is annoying. If we promoted UInt + Int to Int instead of UInt then this particular example would work but others wouldn't.

@yuyichao
Copy link
Contributor

Is there any case (for fixed size integer, {U,}Int{8,16,32,64,128}) that we don't want this to work?

@eschnett
Copy link
Contributor

We have generic comparison routines (comparing signed and unsigned integers). Comparison is very similar to subtraction. Thus one can make the case that mixed signed/unsigned arithmetic should also work.

These comparisons have a slightly more complex implementation since they first test whether e.g. the signed argument is negative (and then returning the obvious result) before performing the actual comparison. A similar approach should work here:

function +(x::Unsigned, y::Signed)
    y<0 && return x - unsigned(-y)
    x + unsigned(y)
end

This isn't quite right yet (since the expression -y can overflow), but the implementation is straightforward.

@JeffBezanson
Copy link
Member

Yes, +1 for leaving conversion and promotion alone, but implementing UInt + Int to handle this.

@Keno
Copy link
Member Author

Keno commented Apr 10, 2016

Ok, has the decision been made to allow this, in which case I'd like to implement this soon. This is super annoying.

@eschnett
Copy link
Contributor

It seems people like the suggestion in general. It's now a question of looking at the details, which only become apparent once there is a concrete implementation (read: "pull request").

@StefanKarpinski
Copy link
Member

x-ref: #9292

@JeffBezanson
Copy link
Member

@StefanKarpinski proposes this basic approach here:

function $op(a::A, b::B) where {A<:BitSigned, B<:BitUnsigned}
    T = promote_type(A, B)
    return $op(a % T, b % T)
end

In other words, use % instead of convert for mixed-signedness operations.

@StefanKarpinski
Copy link
Member

The reasoning is that we don't check for overflow on arithmetic operations so checking for conversion errors when promoting to a common type but then allowing that operation to overflow is silly – you may as well just guarantee that the result is correct in the modulus of the result type.

@JeffBezanson JeffBezanson self-assigned this Sep 22, 2017
JeffBezanson added a commit that referenced this issue Sep 22, 2017
JeffBezanson added a commit that referenced this issue Sep 22, 2017
JeffBezanson added a commit that referenced this issue Sep 25, 2017
JeffBezanson added a commit that referenced this issue Sep 27, 2017
JeffBezanson added a commit that referenced this issue Oct 2, 2017
JeffBezanson added a commit that referenced this issue Oct 10, 2017
JeffBezanson added a commit that referenced this issue Oct 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants