2

When I tried to shift bits on my RGB color experiment I've noticed that I couldn't shift a variable number of bits.

The Swift book only states that you move "a number to the left/right"

„The bitwise left shift operator (<<) and bitwise right shift operator (>>) move all bits in a number to the left or the right by a certain number of places, according to the rules defined below.“

Is it intentional only to be able to shift a predefined number of bits?

// Works fine:
let shiftMe: UInt32 = 0xFF0000
let shiftedConst = shiftMe >> 16

// Doesn't work: 
let shiftMe: UInt32 = 0xFF0000
let shiftValue:Int = 16
let shiftedConst = shiftMe >> shiftValue

The second example won't compile and throws this error:

Could not find an overload for '>>' that accepts the supplied arguments

Is swift designed like this? Is it a bug and fixed in beta3? (I'm still on beta2 atm.)

Community
  • 1
  • 1
D.icon
  • 396
  • 3
  • 14
  • just show the examples https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html – Ashish Kakkad Jul 21 '14 at 11:48
  • simple, while the operators can be overloaded, you can check that there is no `>>` operator overloaded for `UInt32` with `Int`, this operator is overloaded between the _same_ types only (11 integer types are defined only currently). – holex Jul 21 '14 at 13:07

2 Answers2

5

The type of the shift count must match the type of the value being shifted.

shiftValue must be declared UInt32.

let shiftMe: UInt32 = 0xFF0000
let shiftValue:UInt32 = 16
let shiftedConst = shiftMe >> shiftValue

IMO it should not make any difference if the shift count type is UInt8, UInt16, uInt32 or uInt64 (or even the signed versions) since the shift range is smaller than any of these types. Further this is an unnecessary stumbling block that is neither documented nor intuitive.

The error message is both unhelpful and incorrect:

error: :39:20: error: 'UInt32' is not convertible to 'UInt8'
let shiftedConst = shiftMe >> shiftValue

zaph
  • 111,848
  • 21
  • 189
  • 228
  • 1
    I'm thinking about raising a bug report with Apple because it is quite annoying that you have to cast the shift to the same type as the number being shifted. – JeremyP Jul 21 '14 at 12:41
  • @JeremyP, that is not a bug, but the operator is not overloaded only. you can do it for your own, if you feel that anything is missing. – holex Jul 21 '14 at 13:10
  • 2
    @holex This should be reported to Apple, that is the point of Beta software, to obtain problems experienced from a large number of testers. It makes writing code harder and the error message is incorrect and unhelpful. – zaph Jul 21 '14 at 13:14
  • @Zaph, I'm not seeing it as bug, regarding **#1**, you can check which operators are overloaded already in _Swift_ in Xcode in 2 secs; **#2**, you can define custom operators anytime if you feel something is missing. **so**, the large number of developers may be struggling adapting the concept of the _operator overloading_, but that is not bug in Xcode; it is lack of knowledge only, I guess... – holex Jul 21 '14 at 13:19
  • @holex It isn't a question of how the `>>` operator is implemented, it is a question of an implementation that providers reasonably expected usage. At a minimum the error message should be useful. How does one: "check which operators are overloaded already in Swift in Xcode in 2 secs"? – zaph Jul 21 '14 at 13:24
  • @Zaph, I'm not sure how deep you went into _Swift_, but the overloaded operators for `>>` are only with `Int32`, `UInt32`, `Int16`, `UInt16`, `Int8`, `UInt8`, `Int`, `UInt`, `Int64` and `UInt64` only for the _same_ type on the _left_ and _right_ side of the operand. that is currently on my screen in _Xcode6_, it has been available from the very first beta, and anyone can take a look on all built-in overloaded operators. that list has about 400 operators basically, including unary and binary ones. – holex Jul 21 '14 at 13:35
  • 1
    @holex We agree that the overloaded operators for `>>` only allow for the same types on both sides. We are saying that we think this is wrong. The operator would be easier to use and more natural if the right hand side could be `Int` so, for e.g. `for i in 0 ..< bitCount { something = other >> i }` can be done without an ugly type cast. – JeremyP Jul 21 '14 at 13:40
  • @holex I read the Swift iBook **and** looked up `>>` and did not see any information about the type size of the shift count, perhaps I missed that. Further, why would I suspect that `>>` is an overloaded operator? There is no mention that it is an overloaded operator on page 628 under the heading: "Bitwise Left and Right Shift Operators". Where do you find the operator is overloaded in 2 seconds? – zaph Jul 21 '14 at 13:50
  • 1
    I have raised 17746645. If anybody else want to see the overloads changed (or at least a better error message) I suggest they also raise a bug. – JeremyP Jul 21 '14 at 14:02
  • @Zaph, it is not in the book, that is in _XCode6_. I have not found such detailed information in the book about the overloaded operators, but in general info only – that is why I cannot provide direct reference for it. :( but basically _all_ operators in _Swift_ have been defined individually (like `operator infix + { }; func +(lhs: UInt32, rhs: UInt32) -> UInt32`), except the _ternary_ operator. – holex Jul 21 '14 at 14:18
  • @Zaph, everything is defined in the _Swift_ _'framework'_ (? – I'm sure that is a real 'framework' but I could not find better word for it...) main file. I cannot find any direct file name which I can link, but you don't need to ask the same thing from me 5 times, just open that 'framework' (?) and first 1000 lines about the overloaded operators only. – holex Jul 21 '14 at 14:24
  • @Zaph, tell me where you are stuck, because you are referring back to the book time after time – however that is not in the book but that is available in _Xcode6_. check my answer I saved a screenshot of the overloaded operators for the OP (`>>`), and I gave a recommendation how the OP can overload it for custom types to make his code working as is. – holex Jul 21 '14 at 14:47
3

those are the overloaded operators in Swift basically for operator >>, as you see there is no such operator overloading which works on UInt32 with Int:

>> operators


you can overload this operator anytime for your wish, like

func >>(lhs: UInt32, rhs: Int) -> UInt32 {
    return lhs >> UInt32(rhs);
}

and your second code snippet will work without any issue in the future:

let shiftMe: UInt32 = 0xFF0000
let shiftValue: Int = 16
let shiftedConst = shiftMe >> shiftValue

you will find more information about custom operators in Swift here.


in Xcode6 beta, beta2, beta3

holex
  • 23,961
  • 7
  • 62
  • 76
  • Simply: Where did you find this information. How can I find it. – zaph Jul 21 '14 at 14:54
  • 1
    @Zaph, quite simple: choose any _Swift_ types + right click + _Jump to Definition_ + scroll the top of the file (or around the 880th lines for those operators). piece of cake. I did not think it can be an issue for a developer at all... my bad, sorry. – holex Jul 21 '14 at 15:01