如何四舍五入CGFloat

我做了这个方法

+ (CGFloat) round: (CGFloat)f { int a = f; CGFloat b = a; return b; } 

它按预期工作,但只是下降。 如果这是一个负数,它仍然下降。

这只是我所做的一个快速的方法,它不是很重要,它是正确的,我只是把它的四舍五入相机的X和Y值为我的游戏。

这个方法好吗? 它快吗? 还是有更好的解决scheme?

已经有<math.h>可能需要的行为的标准函数,例如: ceilfceilfroundfrintf和nearbyintf(lasf'f'表示“float”版本,没有它的版本是“double”版本)。

使用标准方法不仅是因为它们是标准的,而且是因为它们在边缘情况下更好地工作。

2013更新(jessedc)

iOS不再只有32位。 这个问题还有很多其他的答案,现在更相关。

大多数答案都提到了导入tgmath.h

2017答案

这里的其他答案或者过时或者没有举例。 使用Swift的内置rounded函数很容易将CGFloat rounded

 let x: CGFloat = 3.5 let y = x.rounded() // 4.0 

如果你想把价值四舍五入,你可以使用round

 var x: CGFloat = 3.5 x.round() // 4.0 

舍入规则

如果要更精确地控制数字的舍入方式,可以使用FloatingPointRoundingRule

远离零

 x.rounded(.awayFromZero) 

零以上的数字四舍五入,低于零的数字向下舍入。

 3.000 -> 3.0 3.001 -> 4.0 3.499 -> 4.0 3.500 -> 4.0 3.999 -> 4.0 -3.000 -> -3.0 -3.001 -> -4.0 -3.499 -> -4.0 -3.500 -> -4.0 -3.999 -> -4.0 

 x.rounded(.down) 

将小数点后的数字舍入到下一个较小的整数。 这与floor(x)相同。

 3.000 -> 3.0 3.001 -> 3.0 3.499 -> 3.0 3.500 -> 3.0 3.999 -> 3.0 -3.000 -> -3.0 -3.001 -> -4.0 -3.499 -> -4.0 -3.500 -> -4.0 -3.999 -> -4.0 

到最近或远离零

 x.rounded(.toNearestOrAwayFromZero) // same as x.rounded() 

十进制数字四舍五入到最接近的整数值。 但是,当数值正好在中间(如3.5-3.5 )时,则正数会四舍五入,负数会四舍五入。

它可能有一个复杂的名字,但通常这是一个学习四舍五入的学校。 这也是使用的规则,如果你只是做x.rounded()

 3.000 -> 3.0 3.001 -> 3.0 3.499 -> 3.0 3.500 -> 4.0 *** 3.999 -> 4.0 -3.000 -> -3.0 -3.001 -> -3.0 -3.499 -> -3.0 -3.500 -> -4.0 *** -3.999 -> -4.0 

到最近或甚至

 x.rounded(.toNearestOrEven) 

这与toNearestOrAwayFromZero类似,除了现在的.5值四舍五入到整数。

 3.000 -> 3.0 3.001 -> 3.0 3.499 -> 3.0 3.500 -> 4.0 *** 3.999 -> 4.0 4.500 -> 4.0 *** -3.000 -> -3.0 -3.001 -> -3.0 -3.499 -> -3.0 -3.500 -> -4.0 *** -3.999 -> -4.0 -4.500 -> -4.0 *** 

趋于零

 x.rounded(.towardZero) 

这只是切断任何十进制值的效果。 如果你需要一个Int你可以用Int(x)做同样的事情。

 3.000 -> 3.0 3.001 -> 3.0 3.499 -> 3.0 3.500 -> 3.0 3.999 -> 3.0 -3.000 -> -3.0 -3.001 -> -3.0 -3.499 -> -3.0 -3.500 -> -3.0 -3.999 -> -3.0 

向上

 x.rounded(.up) 

这与.down相反。 所有的十进制数都被四舍五入。 这和ceil(x)是一样的。

 3.000 -> 3.0 3.001 -> 4.0 3.499 -> 4.0 3.500 -> 4.0 3.999 -> 4.0 -3.000 -> -3.0 -3.001 -> -3.0 -3.499 -> -3.0 -3.500 -> -3.0 -3.999 -> -3.0 

笔记

  • 不要忘记考虑负面的价值。
  • roundrounded的结果仍然是CGFloat 。 如果你需要一个Int你必须把它转换成Int(myCGFloat)
  • 无需再使用C(math)函数round(x)ceil(x)floor(x) 。 但是,如果您使用它们,则它们将同时处理64位和32位体系结构,因此您可能在roundfceilfroundf看到的任何答案都已过时。

一个CGFloat被定义为一个double或者一个float ,所以你可以像任何其他真正的types一样把它们四舍五入:

 CGFloat round(CGFloat aFloat) { return (int)(aFloat + 0.5); } 

请注意,虽然这与浮点数足够小,以携带一小部分,它可能会在大的值奇怪。

尝试#import "tgmath.h"

<tgmath.h>头文件将包含头文件<math.h><complex.h> ,并将定义几个types通用的macros。

你正在重新发明轮子 – 这是一个C的问题,而不是目标C.只需使用标准的C round()函数。

为了使用32位和64位,你可以创build自己的macros

 #ifndef CGFLOAT_CEIL #ifdef CGFLOAT_IS_DOUBLE #define CGFLOAT_CEIL(value) ceil(value) #else #define CGFLOAT_CEIL(value) ceilf(value) #endif #endif 

Ps这不是问题的答案,而是关于如何使用32/64位值的问题的补充。

在像MyMacros.h这样的文件中定义它,然后在myapp-Prefix.pch中添加一个导入

另外请记住,selectCGFloat作为你的函数的前缀可能是一个风险,因为苹果可能会像这样添加一个macros,这就是为什么#ifndef CGFLOAT_CEIL