简体   繁体   English

使用 CGFloat 和 float 有什么区别?

[英]What's the difference between using CGFloat and float?

I tend to use CGFloat all over the place, but I wonder if I get a senseless "performance hit" with this.我倾向于到处使用 CGFloat,但我想知道我是否会因此而获得毫无意义的“性能冲击”。 CGFloat seems to be something "heavier" than float, right? CGFloat 似乎比 float 更“重”,对吧? At which points should I use CGFloat, and what makes really the difference?我应该在哪些情况下使用 CGFloat,真正的区别是什么?

As @weichsel stated, CGFloat is just a typedef for either float or double .正如@weichsel 所说, CGFloat 只是floatdouble You can see for yourself by Command-double-clicking on "CGFloat" in Xcode — it will jump to the CGBase.h header where the typedef is defined.您可以通过 Command 双击 Xcode 中的“CGFloat”亲眼看到——它会跳转到定义 typedef 的 CGBase.h 头文件。 The same approach is used for NSInteger and NSUInteger as well.同样的方法也用于 NSInteger 和 NSUInteger。

These types were introduced to make it easier to write code that works on both 32-bit and 64-bit without modification.引入这些类型是为了更轻松地编写无需修改即可在 32 位和 64 位上运行的代码。 However, if all you need is float precision within your own code, you can still use float if you like — it will reduce your memory footprint somewhat.但是,如果您只需要在您自己的代码中使用float精度,您仍然可以根据需要使用float ——它会在一定程度上减少您的内存占用。 Same goes for integer values.整数值也是如此。

I suggest you invest the modest time required to make your app 64-bit clean and try running it as such, since most Macs now have 64-bit CPUs and Snow Leopard is fully 64-bit, including the kernel and user applications.我建议您投入适量的时间使您的应用程序变得 64 位干净并尝试运行它,因为现在大多数 Mac 都有 64 位 CPU,而 Snow Leopard 是完全 64 位的,包括内核和用户应用程序。 Apple's 64-bit Transition Guide for Cocoa is a useful resource. Apple 的Cocoa 64 位过渡指南是一个有用的资源。

CGFloat is a regular float on 32-bit systems and a double on 64-bit systems CGFloat 是 32 位系统上的常规浮点数和 64 位系统上的双精度数

typedef float CGFloat;// 32-bit
typedef double CGFloat;// 64-bit

So you won't get any performance penalty.所以你不会得到任何性能损失。

As others have said, CGFloat is a float on 32-bit systems and a double on 64-bit systems.正如其他人所说,CGFloat 在 32 位系统上是一个浮点数,在 64 位系统上是一个双精度数。 However, the decision to do that was inherited from OS X, where it was made based on the performance characteristics of early PowerPC CPUs.然而,这样做的决定是从 OS X 继承而来的,它是根据早期 PowerPC CPU 的性能特征做出的。 In other words, you should not think that float is for 32-bit CPUs and double is for 64-bit CPUs.换句话说,您不应该认为 float 是针对 32 位 CPU 的,而 double 是针对 64 位 CPU 的。 (I believe, Apple's ARM processors were able to process doubles long before they went 64-bit.) The main performance hit of using doubles is that they use twice the memory and therefore might be slower if you are doing a lot of floating point operations. (我相信,Apple 的 ARM 处理器在进入 64 位之前就能够处理双精度数。)使用双精度数的主要性能影响是它们使用两倍的内存,因此如果您进行大量浮点运算,速度可能会更慢.

Objective-C目标-C

From the Foundation source code, in CoreGraphics' CGBase.h :来自 Foundation 源代码,在 CoreGraphics 的CGBase.h

/* Definition of `CGFLOAT_TYPE', `CGFLOAT_IS_DOUBLE', `CGFLOAT_MIN', and
   `CGFLOAT_MAX'. */

#if defined(__LP64__) && __LP64__
# define CGFLOAT_TYPE double
# define CGFLOAT_IS_DOUBLE 1
# define CGFLOAT_MIN DBL_MIN
# define CGFLOAT_MAX DBL_MAX
#else
# define CGFLOAT_TYPE float
# define CGFLOAT_IS_DOUBLE 0
# define CGFLOAT_MIN FLT_MIN
# define CGFLOAT_MAX FLT_MAX
#endif

/* Definition of the `CGFloat' type and `CGFLOAT_DEFINED'. */

typedef CGFLOAT_TYPE CGFloat;
#define CGFLOAT_DEFINED 1

Copyright (c) 2000-2011 Apple Inc.版权所有 (c) 2000-2011 Apple Inc.

This is essentially doing:这基本上是在做:

#if defined(__LP64__) && __LP64__
typedef double CGFloat;
#else
typedef float CGFloat;
#endif

Where __LP64__ indicates whether the current architecture* is 64-bit.其中__LP64__表示当前架构* 是否为 64 位。

Note that 32-bit systems can still use the 64-bit double , it just takes more processor time, so CoreGraphics does this for optimization purposes, not for compatibility.请注意,32 位系统仍然可以使用 64 位double ,只是需要更多的处理器时间,因此 CoreGraphics 这样做是为了优化目的,而不是为了兼容性。 If you aren't concerned about performance but are concerned about accuracy, simply use double .如果您不关心性能但关心准确性,只需使用double

Swift迅速

In Swift, CGFloat is a struct wrapper around either Float on 32-bit architectures or Double on 64-bit ones (You can detect this at run- or compile-time with CGFloat.NativeType ) and cgFloat.native .在 Swift 中, CGFloat是 32 位架构上的Float或 64 位架构上的Double (您可以在运行或编译时使用CGFloat.NativeType )和cgFloat.nativestruct包装器。

From the CoreGraphics source code, in CGFloat.swift.gyb :来自 CoreGraphics 源代码, CGFloat.swift.gyb

public struct CGFloat {
#if arch(i386) || arch(arm)
  /// The native type used to store the CGFloat, which is Float on
  /// 32-bit architectures and Double on 64-bit architectures.
  public typealias NativeType = Float
#elseif arch(x86_64) || arch(arm64)
  /// The native type used to store the CGFloat, which is Float on
  /// 32-bit architectures and Double on 64-bit architectures.
  public typealias NativeType = Double
#endif

*Specifically, long s and pointers, hence the LP . *特别是long s 和指针,因此是LP See also: http://www.unix.org/version2/whatsnew/lp64_wp.html另见: http : //www.unix.org/version2/whatsnew/lp64_wp.html

just mention that - Jan, 2020 Xcode 11.3/iOS13只是提一下 - 2020 年 1 月 Xcode 11.3/iOS13

Swift 5斯威夫特 5

From the CoreGraphics source code来自 CoreGraphics 源代码

public struct CGFloat {
    /// The native type used to store the CGFloat, which is Float on
    /// 32-bit architectures and Double on 64-bit architectures.
    public typealias NativeType = Double

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM