【问题标题】:Replacement for `fabs`, `fmax`, etc. for use with CGFloat on 64-bit iOS devices替换 `fabs`、`fmax` 等,用于 64 位 iOS 设备上的 CGFloat
【发布时间】:2013-10-21 22:51:31
【问题描述】:

问题

考虑这样的布局代码:

CGFloat descriptionHeight = // height of a paragraph of text with zero or more words;
CGFloat imageHeight = // height of an image;
CGFloat yCoordinateOfSomeOtherView = fmax(descriptionHeight, imageHeight) + 5.0f;

如何重写第三行以支持 64 位 iOS 设备?

(当前代码没有考虑yCoordinateOfSomeOtherViewfloat还是double。)

选项

几个选项(我不确定哪个最好):

1。定义我自己的宏

#if defined(__LP64__) && __LP64__
#define cgfmax(x,y) fmaxf(x,y)
#else
#define cgfmax(x,y) fmax(x,y)
#endif

然后我可以将fmax 替换为cgfmax

2。使用tgmath.h

This Stack Overflow answer 从 2011 年开始建议将 math.h 替换为 tgmath.h。这会将fmax 的实现替换为对每个参数调用__typeof__ 并根据参数类型返回fmaxfmaxf

3。忽略这个问题

由于 CGFloats 与布局相关,将float 存储到double 中可能导致的数据丢失通常是微不足道的。也就是说,它们将代表像素的一小部分。

总结

我正在寻找以前做过 32 位到 64 位转换的人的任何其他选项或有用的建议。

【问题讨论】:

  • 是的,布局内容并没有真正达到 32 位的限制。所以它可能不会成为问题,但做心理锻炼以供将来参考是很有趣的。

标签: ios objective-c cocoa-touch cgfloat


【解决方案1】:

float 转换为double 时不会发生任何“数据丢失”。这种转换总是准确的。

您的解决方案 1 和 2 在语义上完全等效,但 (2) 在风格上更正确。

您的解决方案 3 在形式上是不等价的;它可能会在 float 和 double 之间产生额外的转换,这可能会使其效率稍低(但实际结果是相同的)。

基本上没关系,但使用tgmath

【讨论】:

  • 对不起,我的意思是相反的。 (“数据丢失”是指将 64 位值分配给 32 位类型时截断它们。)也就是说,两个doubles 将进入fmax,一个float 将出现出来。
  • @AaronBrager: 当然可以,但在您的情况下,您知道fmax 的参数最初是CGFloats,这意味着它们的最大值(返回值)完全可以表示为@987654329 @,所以不能四舍五入。结果仍然是准确的。
  • 是的,我不会担心它(我个人只会使用 fmax 等),除非您测量真正的性能问题。
  • @StephenCanon 澄清一下我理解正确:结果仍然是准确的,因为fmax 的实现没有分配任何东西;它只返回它的两个参数之一。但是如果fmax 的实现将值赋给一个新的float 然后返回这个变量,可能会出现截断。对吗?
  • @AaronBrager 不会发生截断,因为保证结果的值可以精确地表示为 CGFloat。分配不参与其中。
猜你喜欢
  • 2014-01-09
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-15
相关资源
最近更新 更多