如何对 CGFloat 进行四舍五入

发布于 2024-08-29 17:58:07 字数 252 浏览 2 评论 0原文

我做了这个方法,

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

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

这只是我制作的一个快速方法,正确舍入并不是很重要,我只是为我的游戏舍入了相机的 x 和 y 值。

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

I made this method

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

It works as expected but it only rounds down. And if it's a negative number it still rounds down.

This was just a quick method I made, it isn't very important that it rounds correctly, I just made it to round the camera's x and y values for my game.

Is this method okay? Is it fast? Or is there a better solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

对岸观火 2024-09-05 17:58:07

2018 答案

这里的其他答案要么已经过时,要么没有给出很好的例子。使用 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

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 中看到过任何答案现在已经过时了。

2018 Answer

The other answers here are either dated or don't give good examples. It is easy to round a CGFloat using Swift's built in rounded function.

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

If you want to round the value in place you can use round:

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

Rounding Rules

If you want more precise control over how numbers are rounded, you can use a FloatingPointRoundingRule.

Away from zero

x.rounded(.awayFromZero)

Numbers above zero are rounded up and numbers below zero are rounded down.

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)

Rounds any number with a decimal value down to the next smaller whole number. This is the same as 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()

Decimal numbers get rounded to the nearest integer value. However, when the value is exactly in the middle (like 3.5 or -3.5) then positive numbers get rounded up and negative numbers get rounded down.

It may have a long complicated name, but this is normally how one learns rounding in school. It is also the rule used if you just do 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)

This is similar to toNearestOrAwayFromZero, except now the .5 values get rounded to the even whole number.

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)

This just has the effect of cutting off any decimal values. If you needed an Int you could do the same thing with 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)

This is the opposite of .down. All decimal numbers are rounded up. This is the same as 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

Notes

  • Don't forget to take negative values into account.
  • The results of round and rounded are still CGFloat. If you need an Int you have to convert it like Int(myCGFloat).
  • There is no need to use the C math functions round(x), ceil(x) and floor(x) anymore. However, if you do use them, they handle both 64 and 32 bit architecture so any answers you may have seen with roundf, ceilf and floorf are now obsolete.
深空失忆 2024-09-05 17:58:07

中已经存在您可能需要的具有行为的标准函数,例如:floorfceilf
roundfrintfnearbyintf (lasf 'f' 表示“浮动”版本,没有它的版本是“双”版本)。

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

2013 更新 (jessedc)

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

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

There are already standard functions with behaviors you might need in <math.h> such as: floorf, ceilf,
roundf, rintf and nearbyintf (lasf 'f' means "float" version, versions without it are "double" versions).

It is better to use standard methods not only because they are standard, but because they work better in edge cases.

2013 Update (jessedc)

iOS is no longer only 32 bit. There are a number of other answers to this question that are now more relevant.

Most answers mention importing tgmath.h

故事还在继续 2024-09-05 17:58:07

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

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

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

A CGFloat is typedef'd to either a double or a float, so you can round them like any other real type:

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

Note that while this works with floats small enough to carry a fraction, it may act weird on large values.

乙白 2024-09-05 17:58:07

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

You are reinventing the wheel - and this is a C question, not Objective C. Just use the standard C round() function.

錯遇了你 2024-09-05 17:58:07

尝试#import "tgmath.h"

标头将包含标头 并将定义几个类型通用宏。

Try #import "tgmath.h".

The <tgmath.h> header will include the headers <math.h> and <complex.h> and will define several type-generic macros.

爱要勇敢去追 2024-09-05 17:58:07

对于使用 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 是

For working with 32 and 64 bit you can create your own macro's like

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

Ps this isn't an answer for the question but an addition for the question about how to work with 32/64 bit values.

Define this in a file like MyMacros.h and than add an import in the myapp-Prefix.pch

Also remember that choosing CGFloat as prefix for your function can be a risk since apple might add a macro like this them self so that is why the #ifndef CGFLOAT_CEIL is

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文