1

The following Swift code fails to compile and I simply don't see what's the problem:

while fabsf(newPercentage - percentage) < 0.006 {
     newPercentage = ((CGFloat)(arc4random() % 220) - 110) * 0.0001;
}

The first line has the following compilation error message: Cannot invoke '<' with an argument list of type '(Float, FloatLiteralConvertible)'

But I don't understand since fabsf returns a Float, and my constant is a Float.

For future reference, here is the Objective-C code I'm trying to translate to Swift:

CGFloat percentage = 0.0f;
for (NSInteger i = 0; i < RotationCount; i++) {
    // ensure that each angle is different enough to be seen
    CGFloat newPercentage = 0.0f;
    do {
        newPercentage = ((CGFloat)(arc4random() % 220) - 110) * 0.0001f;
    } while (fabsf(percentage - newPercentage) < 0.006);
    percentage = newPercentage;

    CGFloat angle = 2 * M_PI * (1.0f + percentage);
    CATransform3D transform = CATransform3DMakeRotation(angle, 0.0f, 0.0f, 1.0f);

    [rotations addObject:[NSValue valueWithCATransform3D:transform]];
}
Sebastien
  • 3,583
  • 4
  • 43
  • 82

2 Answers2

1

The problem is that your newPercentage and percentage are not Floats. They are CGFloats. There is a big difference. You must create a Float here:

while fabsf(Float(newPercentage - percentage)) < 0.006 {}

Also, it isn't what you asked about, but note the technique for conversion - you create a new object initialized from the old. This code of yours is not Swift:

(CGFloat)(arc4random() % 220)

You are still mentally living in the world of C and Objective-C, where there are cast-conversions and casting is done by putting the name of a type in parentheses. There's none of that in Swift.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • But then shouldn't the compiler be complaining about arguments to `fabsf`? The error complains about invoking `<` with arguments of type `Float` (the result from `fabsf`) and `FloatLiteralConvertible`, which sounds like just what you'd expect `<` to be able to handle. – Scott Hunter Dec 24 '14 at 18:31
  • THe weird thing is that both percentage and newPercentage are declared as 'var percentage = 0.0' so I would think they are both Floats. And indeed the compiler didn't complain about the argument to fabsf. Yet, when I add the Float() around newPercentage - percentage, the compiler doesn't complain anymore. About the other casting comment, you are right, I am indeed translating some Objective-C code from a tutorial into Swift code. – Sebastien Dec 24 '14 at 18:35
  • 1
    "I would think". That and a dime won't get you a phone call. Don't think; know. By default, `percentage` declared that way would be a Double, not a Float. Either way, my answer applies. – matt Dec 24 '14 at 19:03
  • 1
    "shouldn't the compiler" That's a completely different issue. The badness of the Swift's compiler error messages is a trope. Don't even try to decipher this one. File a bug report. – matt Dec 24 '14 at 19:03
  • @matt The phrase used to be "X and fifty cents will buy you a cup of coffee". Those were the halcyon days before Starbucks and a cup of coffee that costs more than a decent app. :( – Abizern Dec 24 '14 at 19:17
0

Here is the full translation of the Objective-C code I posted in the question. I don't know if it's the simplest possible one, but it's one that compiles.

var percentage:Float = 0.0
for var i = 0; i < RotationCount; i++ {
    var newPercentage:Float = 0.0
    do {
       newPercentage = Float(Int(arc4random() % 220) - 110) * 0.0001;
    } while fabsf(Float(newPercentage - percentage)) < 0.006
   percentage = newPercentage

   var angle = 2.0 * Float(M_PI) * (1.0 + percentage)
   var transform = CATransform3DMakeRotation(CGFloat(angle), 0.0, 0.0, 1.0)
   self.rotations.append(transform)
}

I really hope Apple will do something to ease with all those implicit type conversions because it's really a pain right now.

Sebastien
  • 3,583
  • 4
  • 43
  • 82
  • Well, I don't think they are going to. See my question and answer here: http://stackoverflow.com/questions/24108827/swift-numerics-and-cgfloat-cgpoint-cgrect-etc You wouldn't think that a language could manage to exist with so much manual numeric conversion, but Swift does, so we'd all just better get used to it. – matt Dec 24 '14 at 19:05
  • Oh, and I forgot: welcome to the code monkey world of hand-translating Objective-C into Swift. :) – matt Dec 24 '14 at 19:11
  • Thanks for the warm welcome Matt. By the way, I read your book to get acquainted with Swift. Awesome work. – Sebastien Dec 24 '14 at 19:16
  • By sheer chance I am currently working on writing a Swift tutorial and I am on _exactly_ the section about numeric coercions! – matt Dec 24 '14 at 19:24