如何围绕CGFloat

时间:2010-04-19 11:57:54

标签: ios objective-c math cgfloat

我制作了这个方法

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

它按预期工作但它只是向下舍入。如果它是一个负数,它仍然会向下舍入。

这只是我制作的一种快速方法,它正确地进行正确计算并不是非常重要,我只是将它用于围绕相机的x和y值进行游戏。

这种方法还可以吗?它快吗?或者有更好的解决方案吗?

6 个答案:

答案 0 :(得分:48)

2018答案

此处的其他答案要么过时,要么没有举出好的例子。使用Swift的内置CGFloat函数很容易对rounded进行舍入。

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

如果您要对值进行四舍五入,可以使用round

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

舍入规则

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

Away from zero

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

Down

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

To nearest or away from zero

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

To nearest or even

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   ***

Toward zero

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

Up

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数学函数round(x)ceil(x)floor(x)。但是,如果您使用它们,它们可以同时处理64位和32位架构,因此您在roundfceilffloorf看到的任何答案现已过时。

答案 1 :(得分:26)

<math.h>中已存在标准函数,其中包含您可能需要的行为,例如:floorfceilfroundfrintfnearbyintf(lasf'f'表示“浮动”版本,没有它的版本是“双”版本。)

最好使用标准方法,不仅因为它们是标准方法,而且因为它们在边缘情况下效果更好。

2013年更新(jessedc)

iOS不再只是32位。此问题还有许多其他答案现在更具相关性。

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

答案 2 :(得分:5)

CGFloatdoublefloat的类型定义,因此您可以像其他任何实际类型一样对它们进行舍入:

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

请注意,虽然这适用于小到足以携带分数的浮点数,但它对大值可能会很奇怪。

答案 3 :(得分:1)

尝试#import "tgmath.h"

<tgmath.h>标头将包含标头<math.h><complex.h>,并将定义多个类型通用宏。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

对于使用32位和64位,您可以创建自己的宏,如

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

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

在MyMacros.h等文件中定义,然后在myapp-Prefix.pch中添加导入

还要记住,选择CGFloat作为你的函数的前缀可能是一个风险,因为苹果可能会添加一个这样的宏,这就是为什么#ifndef CGFLOAT_CEIL