CGFloat Float fix to one type

AI was getting confused and kept correcting, but didn’t have a overriding translation.

Answered by DTS Engineer in 902217022

Your question is a little cryptic, but I think it is about CGFloat and which type it actually maps to. That turned out to have an interesting story behind it, so I thought I'd write something up to share with the forums community. Here is what I found about the state of CGFloat as of today ~

In current Swift, CGFloat and Double are interchangeable, and you do not have to write a conversion between them. Assignment in either direction, arguments, return values, and mixed arithmetic all compile as they stand. So if the conversions you were adding and removing were between those two, you can delete them.

There is a caveat, and it is the interesting part. CGFloat does not name a fixed format. From CGFloat (https://developer.apple.com/documentation/corefoundation/cgfloat): "The size and precision of this type depend on the CPU architecture." On macOS, iOS, iPadOS, tvOS, and visionOS it is the 64-bit type, so moving a value between it and Double costs nothing. In a watchOS device build it is the 32-bit type. The assignment still compiles there, but assigning from Double narrows to 32 bits.

That matters wherever a specific width is part of the contract: a file format, a wire protocol, a GPU buffer. Serializing geometry on one device and reading it back on another is where this tends to show up. A watch and a phone will not agree on the floating-point width. Depending on the coder, you get a decode error or a value that was quietly narrowed. At those boundaries it is clearer to convert yourself, with Double(x), Float(x), or x.native. The width is then your choice rather than whatever the target happens to use.

The other place the interchangeability stops is types built out of them. [Double] will not assign to [CGFloat], and the same holds for optionals, dictionary values, and function types. If a collection or a closure signature is in the mix, that is where the errors are likely to reappear.

Float is a different case. It is a 32-bit type, it is not interchangeable with either of the other two, and a conversion is always required: Float(someCGFloat) or CGFloat(someFloat). That holds on every platform. Float needs the conversion even in a watchOS build, where CGFloat is itself a 32-bit type. The two situations can look similar in an error message, and only one of them needs the conversion. It is worth knowing which one you are looking at. In C and Objective-C the compiler converts between float and double for you, so this only comes up in Swift.

That is also why older documentation and sample code deserves a second look. When Apple's platforms were 32-bit, CGFloat was a 32-bit floating-point type, and code from that era can still assume it.

If you can post the type you are working with, and one line that produced an error, I am happy to be more specific.

Could you explain the context, show the code, show AI fix, tell which AI…

Without such information the post is without any interest.

A very good post from Quinn to look at: https://developer.apple.com/forums/thread/706527

Your question is a little cryptic, but I think it is about CGFloat and which type it actually maps to. That turned out to have an interesting story behind it, so I thought I'd write something up to share with the forums community. Here is what I found about the state of CGFloat as of today ~

In current Swift, CGFloat and Double are interchangeable, and you do not have to write a conversion between them. Assignment in either direction, arguments, return values, and mixed arithmetic all compile as they stand. So if the conversions you were adding and removing were between those two, you can delete them.

There is a caveat, and it is the interesting part. CGFloat does not name a fixed format. From CGFloat (https://developer.apple.com/documentation/corefoundation/cgfloat): "The size and precision of this type depend on the CPU architecture." On macOS, iOS, iPadOS, tvOS, and visionOS it is the 64-bit type, so moving a value between it and Double costs nothing. In a watchOS device build it is the 32-bit type. The assignment still compiles there, but assigning from Double narrows to 32 bits.

That matters wherever a specific width is part of the contract: a file format, a wire protocol, a GPU buffer. Serializing geometry on one device and reading it back on another is where this tends to show up. A watch and a phone will not agree on the floating-point width. Depending on the coder, you get a decode error or a value that was quietly narrowed. At those boundaries it is clearer to convert yourself, with Double(x), Float(x), or x.native. The width is then your choice rather than whatever the target happens to use.

The other place the interchangeability stops is types built out of them. [Double] will not assign to [CGFloat], and the same holds for optionals, dictionary values, and function types. If a collection or a closure signature is in the mix, that is where the errors are likely to reappear.

Float is a different case. It is a 32-bit type, it is not interchangeable with either of the other two, and a conversion is always required: Float(someCGFloat) or CGFloat(someFloat). That holds on every platform. Float needs the conversion even in a watchOS build, where CGFloat is itself a 32-bit type. The two situations can look similar in an error message, and only one of them needs the conversion. It is worth knowing which one you are looking at. In C and Objective-C the compiler converts between float and double for you, so this only comes up in Swift.

That is also why older documentation and sample code deserves a second look. When Apple's platforms were 32-bit, CGFloat was a 32-bit floating-point type, and code from that era can still assume it.

If you can post the type you are working with, and one line that produced an error, I am happy to be more specific.

Thank you.

I have started cleaning a bit to something to send you. I'm worried now that I might not have trouble fixing.

I had a long break while Xcode itself had refused to launch and it got fixed somehow today.

I have to go to an appointment now.

I'll see if I have good news or bad news for you later.

Float(CGFloat(..)) is not the same to compiler as nothing.

Agent GTP5 wants to insert floats.

I wonder if the entire swift file could be in CGFloats?

I’ll send a peculiar structure the Agent made.

i’m taking out floats, but each time there’s a time delay and editing retains the splash screen of the past.

Text editing evidently involves something to do with multiprocessing

Is that so?

wish I could take all floats out.

Would you know an easy way to do this?

Down to one error and must rest for clarity.

Agent was confusing. Here's file I was working on:

/Users/paulsheldon2/Downloads/DanceSkeleton/DanceSkeleton/ContentsView.swift

CGFloat Float fix to one type
 
 
Q