【问题标题】:Objective C. Casting int to float目标 C. 将 int 转换为 float
【发布时间】:2011-08-09 09:31:38
【问题描述】:

对于这样的一般性问题很抱歉,但是在 ObjC 中将 int 转换为 float 的最佳(尽可能快且最安全)的方法是什么:

第一

int b = 10;
float a = [[NSNumber numberWithInt: b] floatValue]

会有NSNumber实例和消息numberWithIntfloatValue将被发送,对吧?

第二

int b = 10;
float a = (float) b;

C 风格:this with call some subroutine?

或者其他方式?

为什么?

【问题讨论】:

  • 使用演员表。它不调用子程序。编译器将确保使用正确的汇编代码。
  • 不要使用演员表。一个普通的float a = b; 就足够了。

标签: objective-c c floating-point int


【解决方案1】:

C 风格的类型转换是最清晰、最容易阅读的。如果我碰巧找到了创建 NSNumber 对象只是为了让它进行转换的代码,那会让我想知道“他为什么这样做?除了普通的旧类型转换之外,这里发生了什么?我是什么?不见了?”

至于速度,我怀疑简单的类型转换也会更快 - NSNumber 对象将需要执行几乎相同的操作来进行转换,并且在顶部有对象创建和消息传递的额外开销其中。但在所有这些情况下,不要猜测 - 测量。分析您的代码以查看转换是否是一个足以引起您注意的瓶颈。

【讨论】:

  • 我只想填充CGRect 结构大约10次,发现我不知道如何用最好的方式进行转换
  • 那么问题是,用什么填充它?如果你用文字硬编码值填充它们,你可以简单地写NSMakeRect(1.0, 1.0, 1.0, 1.0),不需要转换。另一方面,如果你从 plist 中读取数据,无论如何你都会得到一个 NSNumber 对象,所以只需调用它的-floatValue 方法。从-intValue 类型转换返回值只会造成毫无意义的混淆。最简单的方法几乎总是最好的。
  • 我在 for 循环中从我获取 int 值并将其传递给 CGRect 结构
  • 然后只需使用类型转换。这是最清晰、最容易阅读的,如果你只做十次,那么绝对没有理由浪费时间尝试“优化”它。
【解决方案2】:

既然您询问安全性,您首先需要检查的是您的int 的值是否适合float。否则你会默默地丢失数据。除非价值非常小,否则它不适合。我会改用double,这样你就不用担心这个了,然后做任务:

double d;
d = i;

float 类型的变量很少有任何用途,很像 short...

【讨论】:

  • -1 float 的最大值比 int 的最大值大大。 float 的最大值定义为 3.40282347 x 10^38,而 int 的最大值定义为 2147483647,这使得 float 的最大值为 1.58456316 × 10^29 倍
  • @nick:仅仅因为最大值较大并不意味着任何int 都适合floatfloat(IEEE 单精度)尾数只有 24 个值位。这意味着如果一个整数大于 2^24-1,则它仅在低位全为零时才适合浮点数。也就是说,0x1fffffe 适合但 0x1ffffff 不适合。如果您不相信我,请尝试将后者转换为浮点数并返回,您会看到值已更改。 (如果您在 x86 上使用 GCC,请务必使用 -ffloat-store 否则它实际上可能无法转换。)
  • 你说得对,我从来不知道,我很抱歉,但这对我来说确实有点奇怪。我正在尝试删除 -1,但它告诉我投票已锁定:(
【解决方案3】:

当两个数字基元之间的直接类型转换可用时,我真的不认为需要 NSNumber 对象。无论如何,NSNumber 类并不只是用于类型转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-12
    • 2019-12-04
    • 2017-09-04
    • 2011-11-02
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多