Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion due to Swift lacking implicit conversion of CGFloat

Trying to do arithmetic in a function that returns `CGFloat, I get an error:

Couldn't find overload for '/' that accepts supplied arguments

func kDCControlDegreesToRadians(x : CGFloat) -> CGFloat
{ 
     return (M_PI * (x) / 180.0) // error is here. 
}

Has anyone else seen this type of issue?

like image 794
Mani Avatar asked Jun 09 '14 10:06

Mani


3 Answers

This is a problem with double to float conversion.

On a 64-bit machine, CGFloat is defined as double and you will compile it without problems because M_PI and x are both doubles.

On a 32-bit machine, CGFloat is a float but M_PI is still a double. Unfortunately, there are no implicit casts in Swift, so you have to cast explicitly:

return (CGFloat(M_PI) * (x) / 180.0)

The type for 180.0 literal is inferred.

In Swift 3

M_PI is deprecated, use CGFloat.pi instead:

return (x * .pi / 180.0)
like image 87
Sulthan Avatar answered Nov 08 '22 05:11

Sulthan


In this specific case I have a cute trick to recommend

let π = CGFloat(M_PI)

Unicode everywhere, and π is easy to get to with Opt+P

like image 26
Joel Pettersson Avatar answered Nov 08 '22 04:11

Joel Pettersson


Its best to abstract away the complexity. First create an extension

extension Double {
    /** Converts the specified value in degrees into radians. */
    func degrees() -> CGFloat {
        return CGFloat(self) * CGFloat(M_PI / 180.0)
    }
}

then use it in your code such as the following example

let angle = 30.0.degrees()
let transform = CGAffineTransformRotate(self.sliderControl.transform, angle);

At first I was reluctant to extend Double because I don't like creating a custom tailored use of the language (from coding horrors found in C++). However, practical experience has shown this to being a way of abstraction natural to the language.

like image 1
Faisal Memon Avatar answered Nov 08 '22 05:11

Faisal Memon