Swift binary operator '+' cannot be applied to two CGFloat operands
Asked Answered
P

5

17

I am writing a function in Swift to detect which hexagon I am clicking on. But I ran into a peculiar error message stating that I cannot add two CGFloats. Whatever I did, e.g. changing let to var, declare and assign separately, did not work. I guess there must be something else wrong, but I cannot find it. The code is as follows:

func pointToCoordinate(position: CGPoint) -> (Int, Int) {
        var gridHeight = 2 * singleRadius / sqrt(CGFloat(3)) * 1.5
        var gridWidth = 2 * singleRadius
        var halfWidth = singleRadius

        var relativePosition = CGPoint(x: position.x - totalRadius / 2, y: position.y - totalRadius / 2)
        println((relativePosition.y / gridHeight))
        var row = -(cgfloatToInt)(relativePosition.y / gridHeight)
        var column: Int

        println((relativePosition.x + halfWidth * CGFloat(row + 1)) / (gridWidth))
        column = cgfloatToInt((relativePosition.x + halfWidth * CGFloat(row + 1)) / (gridWidth))

//        var innerY: CGFloat = CGFloat(relativePosition.y) + CGFloat(gridHeight * row)
        var innerX = relativePosition.x
        var innerY = relativePosition.y

        innerY = innerY - CGFloat(gridHeight * row)

        println((innerX, innerY))
        return (column, row)
    }

Error Message

Phonetist answered 6/6, 2015 at 0:14 Comment(0)
N
56

The error message is wrong. The problem is that you are trying to multiply an Int and a CGFloat.

Replace:

innerY = innerY - CGFloat(gridHeight * row)

with:

innerY = innerY - gridHeight * CGFloat(row)

The answer above is for the current version of your code. For the commented out version that corresponds to the error message you posted:

Replace:

var innerY: CGFloat = CGFloat(relativePosition.y) + CGFloat(gridHeight * row)

with

var innerY: CGFloat = CGFloat(relativePosition.y) + gridHeight * CGFloat(row)
Nikko answered 6/6, 2015 at 0:39 Comment(3)
"The error message is wrong" is still very relevant regarding this same message in Xcode 8/Swift 3.Villada
@SpaceDog I find Swift compiler errors run the gamut from telling you what you need to know, accurate but only helpful to a compiler writer, and flat out wrong. This case was flat out wrong.Nikko
@Nikko - I was by adding a CGFloat to a Float a few moments ago and the error message was "binary operator + cannot be applied to CGFloat" what is a bullcrap message. The correct message would have to be "you cannot add CGFloats and Floats". Binary operator is a confuse term because you think of binary operations. I create apps since 2008. I never saw a single Xcode error message pointing to the correct problem. They are all created to inflict maximum pain.Slut
A
5

Looking through all the answers, castings, conversion and extensions, I think the best solution yet to say for Swift is Operator Overload. Code sample below for Swift 3.0:

/// overloads -/+ between a cgfloat on the left and an int/double on the right
func - (left: CGFloat, right: Double) -> CGFloat {
    return left - CGFloat(right);
}

func - (left: CGFloat, right: Int) -> CGFloat {
    return left - CGFloat(right);
}

func + (left: CGFloat, right: Double) -> CGFloat {
    return left + CGFloat(right);
}

func + (left: CGFloat, right: Int) -> CGFloat {
    return left + CGFloat(right);
}

Put this into a global place OUTSIDE of any class. See magic occurs.

Asocial answered 13/1, 2017 at 5:10 Comment(0)
I
3

Indeed, there is something else wrong, this works:

import QuartzCore

let a:CGFloat = 1
let b:CGFloat = 2

let c = a + b
var innerY: CGFloat = CGFloat(1.0) + CGFloat(2.0)

and CGFloat implements the FloatingPointType type

Incurable answered 6/6, 2015 at 0:25 Comment(0)
M
2

iOS 15, Swift 5.x

I had this problem, was solved by unwrapping the value... the floats in my case were optionals.

Macmacabre answered 13/6, 2022 at 13:5 Comment(0)
B
1

Late to join. Based on vacawama's answer, you all know the problem is not having the same data type.
CGFloat needs to be written multiple times sometimes. I found this easier via extension. So sharing an answer. You can create a simple extension like below. Ofcourse, this extension can be further modified.

import CoreGraphics
extension Int {
    var cgf: CGFloat { return CGFloat(self) }
    var f: Float { return Float(self) }
}

extension Float {
    var cgf: CGFloat { return CGFloat(self) }
}

extension Double {
    var cgf: CGFloat { return CGFloat(self) }
}

extension CGFloat {
    var f: Float { return Float(self) }
}

Now we can write

innerY = innerY - gridHeight * row.cgf
Bahrain answered 22/4, 2016 at 19:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.