如何四舍五入CGFloat
我做了这个方法
+ (CGFloat) round: (CGFloat)f { int a = f; CGFloat b = a; return b; }
它按预期工作,但只是下降。 如果这是一个负数,它仍然下降。
这只是我所做的一个快速的方法,它不是很重要,它是正确的,我只是把它的四舍五入相机的X和Y值为我的游戏。
这个方法好吗? 它快吗? 还是有更好的解决scheme?
已经有<math.h>
可能需要的行为的标准函数,例如: ceilf
, ceilf
, roundf
, rintf
和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
笔记
- 不要忘记考虑负面的价值。
-
round
和rounded
的结果仍然是CGFloat
。 如果你需要一个Int
你必须把它转换成Int(myCGFloat)
。 - 无需再使用C(math)函数
round(x)
,ceil(x)
和floor(x)
。 但是,如果您使用它们,则它们将同时处理64位和32位体系结构,因此您可能在roundf
,ceilf
和roundf
看到的任何答案都已过时。
一个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