我编写了这个方法。
+ (CGFloat) round: (CGFloat)f {
int a = f;
CGFloat b = a;
return b;
}
它按预期工作,但只舍去小数部分。如果是负数,它仍然向下舍入。
这只是我制作的一个快速方法,它的正确舍入并不是非常重要,我只是为了舍入我的游戏相机的x和y值而制作了它。
这个方法可行吗?它快吗?还有更好的解决方案吗?
我编写了这个方法。
+ (CGFloat) round: (CGFloat)f {
int a = f;
CGFloat b = a;
return b;
}
它按预期工作,但只舍去小数部分。如果是负数,它仍然向下舍入。
这只是我制作的一个快速方法,它的正确舍入并不是非常重要,我只是为了舍入我的游戏相机的x和y值而制作了它。
这个方法可行吗?它快吗?还有更好的解决方案吗?
这里其他的回答要么已经过时,要么没有给出好的示例。使用Swift内置的rounded
函数很容易将CGFloat
四舍五入。
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)
。round(x)
、ceil(x)
和 floor(x)
。然而,如果你确实使用它们,它们处理 64 位和 32 位体系结构,因此你可能曾经看到的使用 roundf
、ceilf
和 floorf
的答案已经过时了。在<math.h>
中已经有标准函数可以满足您的需求,例如:floorf
, ceilf
,
roundf
, rintf
和nearbyintf
(带'f'的代表"float"版本,不带的代表"double"版本)。
最好使用标准方法,不仅因为它们是标准的,而且因为它们在边缘情况下表现更好。
2013年更新(jessedc)
iOS不再只支持32位。有许多其他回答针对这个问题,现在更加相关。
大多数回答都提到了导入tgmath.h
CGFloat
被typedef为double
或float
,因此您可以像任何其他实数类型一样对它们进行四舍五入:CGFloat round(CGFloat aFloat)
{
return (int)(aFloat + 0.5);
}
round()
用于 doubles
,而 roundf()
用于 floats
。在 32 位系统上,CGFloat
是 float
,而在 64 位系统上是 double
。 - hfossli尝试使用#import "tgmath.h"
。
<tgmath.h>
头文件将包含<math.h>
和<complex.h>
头文件,并定义多个类型通用的宏。
如果要处理32位和64位,您可以创建自己的宏,例如:
#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中添加导入即可。
还要记得选择CGFloat作为函数前缀可能存在风险,因为苹果可能会自己添加这样的宏,所以#ifndef CGFLOAT_CEIL
objective-c
... - gog