# About SE-307: Is the implicit Double to CGFloat conversion a performance hit on 64 bit platforms?

**URL:** <https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581>\
**Category:** Using Swift\
**Tags:** performance, uikit, double, cgfloat\
**Created:** [June 30, 2022, 12:05pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581 "2022-06-30T12:05:32Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![kaiengelhardt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kaiengelhardt/32/406_2.png) [@kaiengelhardt](https://forums.swift.org/u/kaiengelhardt)\
**Post date:** [June 30, 2022, 12:05pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/1 "2022-06-30T12:05:32Z")

</div>

Today a conversation in my development team came up about unifying our usage of `CGFloat` and `Double`. Since [SE-307](https://forums.swift.org/t/se-0307-allow-interchangeable-use-of-cgfloat-and-double-types/45756/8) Swift does the conversion automatically.

I have two questions about that:

1. Is there any performance impact when I pass in `Double` to a `CGFloat` API on 64 bit platforms? Sure, shrinking to `Float` on 32 bit platforms will probably have some performance impact, but for me the 64 bit case is the most relevant one. I have not seen any documentation on the performance implications of this implicit conversion.

2. What's the guidance on custom UIKit classes? Should we continue to use `CGFloat` here or is `Double` the way? (I know, this is technically a question for the Apple Developer Forums, but the questions fits pretty well with the original topic in my opinion.)

---

<div class="post-metadata">

**Author:** ![lukasa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lukasa/32/1232_2.png) [@lukasa](https://forums.swift.org/u/lukasa)\
**Post date:** [June 30, 2022, 12:30pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/3 "2022-06-30T12:30:55Z")

</div>

Per [the documentation](https://developer.apple.com/documentation/corefoundation/cgfloat):

> The size and precision of this type depend on the CPU architecture. When you build for a 64-bit CPU, the CGFloat type is a 64-bit, IEEE double-precision floating point type, equivalent to the Double type. When you build for a 32-bit CPU, the CGFloat type is a 32-bit, IEEE single-precision floating point type, equivalent to the Float type.

So no translation is required on 64-bit platforms.

---

<div class="post-metadata">

**Author:** ![kaiengelhardt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kaiengelhardt/32/406_2.png) [@kaiengelhardt](https://forums.swift.org/u/kaiengelhardt)\
**Post date:** [June 30, 2022, 12:47pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/4 "2022-06-30T12:47:31Z")

</div>

Thank you, both, so that's settled then!

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [June 30, 2022, 3:50pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/5 "2022-06-30T15:50:55Z")

</div>

Remember the weird duck that is arm64\_32 (Apple Watch), which is an ILP32 64-bit architecture. Since `CGFloat == double` only on LP64 platforms, this will result in expansion to ~~Double~~ Float on arm64\_32.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [June 30, 2022, 4:07pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/6 "2022-06-30T16:07:57Z")

</div>

You mean it expands to `Float` on arm64\_32. (Which it does, as it does on armv7k, which arm64\_32 is generally required to match in terms of type sizes and so on.)

I think the right way to understand this is that it doesn't really have anything to do with the architecture and is really just a platform choice. It happens to be true on all current platforms that it follows the pointer width, and that allows a convenient implementation in terms of ` __LP64__ ` in the headers, but if Apple ever introduces another 32-bit platform, they very well might decide to make `CGFloat` use `Double` on it, and that would be a valid choice and code would simply have to adapt.

---

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [July 1, 2022, 3:03pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/7 "2022-07-01T15:03:37Z")

</div>

> [@kaiengelhardt](#):
>
> What's the guidance on custom UIKit classes? Should we continue to use `CGFloat` here or is `Double` the way? (I know, this is technically a question for the Apple Developer Forums, but the questions fits pretty well with the original topic in my opinion.)

The answer here isn’t particularly specific to UIKit so it’s fine to answer here: you should now always use Double. There’s no downside to using Double. We’ve long since moved past the point on currently supported devices where you actually needed to care about using CGFloat because of its actual width. The main reason modern APIs or code continued to use CGFloat was because CGFloat was a different type, and so sticking with it reduced the number of annoying conversions needed. This led to a vicious cycle – more use of CGFloat begat more use of CGFloat. The beauty of SE-0307 is that it heals this problem. APIs and app authors are now able to use Double without any concern for the ergonomic issues it causes.

---

<div class="post-metadata">

**Author:** ![kaiengelhardt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kaiengelhardt/32/406_2.png) [@kaiengelhardt](https://forums.swift.org/u/kaiengelhardt)\
**Post date:** [July 1, 2022, 3:05pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/8 "2022-07-01T15:05:18Z")

</div>

Thank you so much Ben, this is helping me a lot. It's awesome to have an authoritative answer on this topic ❤.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [July 1, 2022, 5:19pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/9 "2022-07-01T17:19:34Z")

</div>

> [@kaiengelhardt](#):
>
> Should we continue to use `CGFloat` here or is `Double` the way?

CGFloats and Doubles are not fully interchangeable, sometimes you are (still) forced to used CGFloats explicitly:

```swift
    let color = UIColor.red
    var white: Double = 0
    var alpha: Double = 0
    color.getWhite(&white, alpha: &alpha) // Error: Cannot convert value of type 'UnsafeMutablePointer<Double>' to expected argument type 'UnsafeMutablePointer<CGFloat>'

```

BTW, just recently I found a case when compiler issued an illegal instruction diagnostic during compilation for some valid swift source that used doubles and CGFoats interchangeably. That crash went away once I added explicit type annotation:

```
var x = 1.0 → var x: CGFloat = 1.0

```

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [July 1, 2022, 5:28pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/10 "2022-07-01T17:28:50Z")

</div>

> [@tera](#):
>
> BTW, just recently I found a case when compiler issued an illegal instruction diagnostic during compilation for some valid swift source that used doubles and CGFoats interchangeably. That crash went away once I added explicit type annotation:

This is well worth a bug report, if you haven't already done so.

---

<div class="post-metadata">

**Author:** ![aerobounce](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/aerobounce/32/14175_2.png) [@aerobounce](https://forums.swift.org/u/aerobounce)\
**Post date:** [July 1, 2022, 6:56pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/11 "2022-07-01T18:56:45Z")

</div>

> [@ben-cohen](#):
>
> you should now always use Double. There’s no downside to using Double.

This is worth quoting, this is cool. Many thanks for clarification!

---

<div class="post-metadata">

**Author:** ![tbkka](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tbkka/32/7532_2.png) [@tbkka](https://forums.swift.org/u/tbkka)\
**Post date:** [July 5, 2022, 5:41pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/12 "2022-07-05T17:41:17Z")

</div>

> [@tera](#):
>
> `// Error: Cannot convert value of type 'UnsafeMutablePointer<Double>' to expected argument type 'UnsafeMutablePointer<CGFloat>'`

This might be worth filing a bug for.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [July 5, 2022, 6:27pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/13 "2022-07-05T18:27:05Z")

</div>

I don't believe that this conversion is expected to work (it can't, because it would be invalid on platforms with CGFloat ~ Float).

---

<div class="post-metadata">

**Author:** ![James\_Dempsey](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/james_dempsey/32/14336_2.png) [@James\_Dempsey](https://forums.swift.org/u/James_Dempsey)\
**Post date:** [July 6, 2022, 3:01pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/14 "2022-07-06T15:01:59Z")

</div>

I just wish this conversion had been in place before SwiftUI APIs all ended using CGFloat. I realize I can just use Double with those APIs, it's just a shame that a next generation UI framework will perpetuate CGFloat in its API for the foreseeable future.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [July 6, 2022, 4:20pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/15 "2022-07-06T16:20:49Z")

</div>

But you can’t “just use Double” if you target watchOS or legacy 32-bit platforms. You can _mostly_ use Double, but if your program is sensitive to rounding error you need to understand the consequences of whether your platform uses Float or Double.

It so happens that a large number of CGFloats are assigned integral multiples of 1/2 or 1/3. But 1/3 isn’t representable as a binary float, and the rounding differs between Double and Float. This can cause problems for cross-platform serialization code.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [July 6, 2022, 5:53pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/16 "2022-07-06T17:53:41Z")

</div>

> [@ksluder](#):
>
> It so happens that a large number of CGFloats are assigned integral multiples of 1/2 or 1/3. But 1/3 isn’t representable as a binary float, and the rounding differs between Double and Float. This can cause problems for cross-platform serialization code.

This is precisely why you should "just use double". `Double` is the same on all supported platforms. If you isolate use of `CGFloat` confined to places where it is explicitly used in UI frameworks, you will not have these problems, because the program state that you want to serialize will be made up of `Double`s instead.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [July 6, 2022, 5:59pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/17 "2022-07-06T17:59:30Z")

</div>

I can tell you from experience there have been many places within the UI frameworks where comparing two CGFloats on 3x devices has gone awry due to one having been computed with different intermediate precision.

In retrospect, it would have been very nice to use some form of rational coordinates, but that would have come at great expense for interoperating with Quartz.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [July 6, 2022, 6:00pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/18 "2022-07-06T18:00:06Z")

</div>

> [@ksluder](#):
>
> I can tell you from experience there have been many places within the UI frameworks where comparing two CGFloats has gone awry due to one having been computed with different intermediate precision.

... which is why any new code should _always use Double_ to avoid this problem.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [July 6, 2022, 6:00pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/19 "2022-07-06T18:00:46Z")

</div>

If you are building on watchOS, the APIs will demand you pass a Float, not a Double.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [July 6, 2022, 6:01pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/20 "2022-07-06T18:01:25Z")

</div>

No, they will demand that you pass a CGFloat, which is where the implicit conversions in question come in. They cannot handle every case, but they can handle quite a few.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [July 6, 2022, 6:03pm UTC](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581/21 "2022-07-06T18:03:53Z")

</div>

CGFloat is Float on watchOS. If you have a Double representation of 1/3, it’s going to be converted to Float somehow when passed to any API that accepts a CGFloat. That approximation of 1/3 will not necessarily be the same as an approximation of 1/3 computed directly from the literal or from some computation that exclusively used Float for intermediate values.

This has been the source of real bugs that the UIKit team has needed to fix, including infinite loops due to insufficient comparison tolerances.

[Next page](https://forums.swift.org/t/about-se-307-is-the-implicit-double-to-cgfloat-conversion-a-performance-hit-on-64-bit-platforms/58581.md?page=2)
