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

type stability of integer types under addition? #9162

Closed
alanedelman opened this issue Nov 26, 2014 · 15 comments
Closed

type stability of integer types under addition? #9162

alanedelman opened this issue Nov 26, 2014 · 15 comments

Comments

@alanedelman
Copy link
Contributor

Sorry if this appears elsewhere, but this took me by surprise

a=uint8(1)
typeof(a+=uint8(1))

results in

Uint64

where I would have expected Uint8.

In MATLAB, for example, the sum of Uint8's is a Uint8, etc.

What's up? Is this intended, or a quick hack that should be fixed?

@timholy
Copy link
Sponsor Member

timholy commented Nov 26, 2014

Fixed in #8420. It was a big change.

@timholy timholy closed this as completed Nov 26, 2014
@StefanKarpinski
Copy link
Sponsor Member

Not sure if I would call it "fixed" so much as changed. The old behavior was quite intentional.

@ivarne
Copy link
Sponsor Member

ivarne commented Nov 26, 2014

But it was never on the list of features users loved about Julia.

@ivarne
Copy link
Sponsor Member

ivarne commented Nov 26, 2014

At least, we got many complaints about the behaviour and no praise.

@timholy
Copy link
Sponsor Member

timholy commented Nov 26, 2014

True enough, @StefanKarpinski.

It's not like it was without merit, it's just that the balance seems to favor the current choice.

@toivoh
Copy link
Contributor

toivoh commented Nov 26, 2014

Let's wait and see how many reactions we get on the new behavior, shall we?
:) I'm not so sure it will be less.

@eschnett
Copy link
Contributor

Wow. This essentially removes C's "integer promotion" from Julia. That should definitively go into the 0.4 release notes. I think it also deserves a separate announcement to the list.

Now -- what is the result of uint8(1) + int8(1)? Does this still automatically convert signed to unsigned integers? That's the other part of C's conversion rules that people don't like, i.e. assuming that UInt has somehow more digits that Int...

@timholy
Copy link
Sponsor Member

timholy commented Nov 26, 2014

It's already in NEWS.md. I completely agree it's a big change, but overall I've been quite surprised about how little trouble it has caused.

There is promotion in cases where the two types differ. You're running 0.4, right? Just try the cases you wonder about (this was merged more than a month ago).

@StefanKarpinski
Copy link
Sponsor Member

julia> 0x1 + 0x1
0x02

julia> UInt(1) + 1
0x0000000000000002

Unfortunately when choosing whether UInt + Int should be Int or Uint there are cases where you may want either one. I wonder if we shouldn't make that a checked operation and return an Int.

@ivarne
Copy link
Sponsor Member

ivarne commented Nov 26, 2014

Int seems more intuitive than Uint to me, but I have no prior experience with such arithmetics. What does other languages do?

@ViralBShah
Copy link
Member

Int does seem more intuitive.

@eschnett
Copy link
Contributor

Returning UInt is more convenient. One uses UInt only in special cases, e.g. when manipulating bits or handling masks. In this case, one needs expressions such as x::UInt - 1 return an UInt again. It is rather rare that one needs to convert a bit mask back to an integer. My point is that UInt often doesn't represent an integer, but something else (e.g. a pixel, character encoding, bit mask), and thus converting to Int wouldn't be useful.

We could also go the safe road: disallow automatic conversions between signed an unsigned types. In this case, we'd need a good syntax for unsigned integer literals, such as e.g. 1u. This would make UInt decidedly second class. I'm afraid this would make ccall much less convenient.

@quinnj
Copy link
Member

quinnj commented Nov 26, 2014

I think I agree with Erik here. In some of the grisu code and SuffixArrays,
whenever you have code dealing with UInts, it's usually for a specific
reason (e.g. representing a Float64 significand), so operations on them are
convenient when they return UInts, but you can still write x::UInt - 1.

On Wed, Nov 26, 2014 at 2:30 PM, Erik Schnetter [email protected]
wrote:

Returning UInt is more convenient. One uses UInt only in special cases,
e.g. when manipulating bits or handling masks. In this case, one needs
expressions such as x::UInt - 1 return an UInt again. It is rather rare
that one needs to convert a bit mask back to an integer. My point is that
UInt often doesn't represent an integer, but something else (e.g. a
pixel, character encoding, bit mask), and thus converting to Int wouldn't
be useful.

We could also go the safe road: disallow automatic conversions between
signed an unsigned types. In this case, we'd need a good syntax for
unsigned integer literals, such as e.g. 1u. This would make UInt
decidedly second class. I'm afraid this would make ccall much less
convenient.


Reply to this email directly or view it on GitHub
#9162 (comment).

@StefanKarpinski
Copy link
Sponsor Member

Yeah, that's the reason it is the way it is now.

@GunnarFarneback
Copy link
Contributor

Mixing precisions and signs is something of a minefield.

julia> 0x1 + 1
2

julia> [0x1] + 1
1-element Array{UInt8,1}:
 0x02

julia> 0x0000000000000001 + 1
0x0000000000000002

julia> 0x00000001 + 1
2

where the last one comes out as unsigned instead of signed if you are on a 32 bit Julia.

My opinion is that if you have an integer type T other than the default (in the sense of unadorned literals) Int, it is probably for a reason, and you want operations between T and T to stay in T, but likewise for operations between T and Int to stay in T.

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

No branches or pull requests

9 participants