90

如何在 Swift 中四舍五入 CGFloat?我试过ceil(CDouble(myCGFloat))了,但这只适用于 iPad Air 和 iPhone 5S。

在另一个模拟设备上运行时,我收到一条错误消息'NSNumber' is not a subtype of 'CGFloat'

4

6 回答 6

126

更新:Apple 现在已经定义了一些 CGFloat 特定版本的常见功能,例如ceil

func ceil(x: CGFloat) -> CGFloat

...专门用于应对 32/64 位差异。如果您只是使用ceilCGFloat 参数,它现在应该适用于所有架构。

我原来的答案:

我认为这非常可怕,但有人能想到更好的方法吗?#if似乎不起作用CGFLOAT_IS_DOUBLE;我认为您仅限于构建配置,从我在条件编译的文档中可以看到

var x = CGFloat(0.5)

#if arch(x86_64) || arch(arm64)
var test = ceil(x)
#else
var test = ceilf(x)
#endif
于 2014-06-12T10:43:55.537 回答
53

使用 Swift 5,您可以选择以下 3 条路径之一来将CGFloat.


#1。使用CGFloat'srounded(_:)方法

FloatingPoint协议为符合它的类型提供了一种rounded(_:)方法。CGFloatrounded(_:)声明如下:

func rounded(_ rule: FloatingPointRoundingRule) -> CGFloat

使用指定的舍入规则将此值返回为整数值。

下面的 Playground 示例代码显示了如何使用rounded(_:)四舍五入的CGFloat值:

import CoreGraphics

let value1: CGFloat = -0.4
let value2: CGFloat = -0.5
let value3: CGFloat = -1
let value4: CGFloat = 0.4
let value5: CGFloat = 0.5
let value6: CGFloat = 1

let roundedValue1 = value1.rounded(.up)
let roundedValue2 = value2.rounded(.up)
let roundedValue3 = value3.rounded(.up)
let roundedValue4 = value4.rounded(.up)
let roundedValue5 = value5.rounded(.up)
let roundedValue6 = value6.rounded(.up)

print(roundedValue1) // prints -0.0
print(roundedValue2) // prints -0.0
print(roundedValue3) // prints -1.0
print(roundedValue4) // prints 1.0
print(roundedValue5) // prints 1.0
print(roundedValue6) // prints 1.0

#2。使用ceil(_:)功能

Darwin提供了一个ceil(_:)具有以下声明的函数:

func ceil<T>(_ x: T) -> T where T : FloatingPoint

下面的 Playground 代码显示了如何使用ceil(_:)来四舍五入一个CGFloat值:

import CoreGraphics

let value1: CGFloat = -0.4
let value2: CGFloat = -0.5
let value3: CGFloat = -1
let value4: CGFloat = 0.4
let value5: CGFloat = 0.5
let value6: CGFloat = 1

let roundedValue1 = ceil(value1)
let roundedValue2 = ceil(value2)
let roundedValue3 = ceil(value3)
let roundedValue4 = ceil(value4)
let roundedValue5 = ceil(value5)
let roundedValue6 = ceil(value6)

print(roundedValue1) // prints -0.0
print(roundedValue2) // prints -0.0
print(roundedValue3) // prints -1.0
print(roundedValue4) // prints 1.0
print(roundedValue5) // prints 1.0
print(roundedValue6) // prints 1.0

#3。使用NumberFormatter

如果您想在同一操作中对 a 进行四舍五入CGFloat并使用样式对其进行格式化,您可以使用NumberFormatter.

import Foundation
import CoreGraphics

let value1: CGFloat = -0.4
let value2: CGFloat = -0.5
let value3: CGFloat = -1
let value4: CGFloat = 0.4
let value5: CGFloat = 0.5
let value6: CGFloat = 1

let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.roundingMode = NumberFormatter.RoundingMode.ceiling
formatter.maximumFractionDigits = 0

let roundedValue1 = formatter.string(for: value1)
let roundedValue2 = formatter.string(for: value2)
let roundedValue3 = formatter.string(for: value3)
let roundedValue4 = formatter.string(for: value4)
let roundedValue5 = formatter.string(for: value5)
let roundedValue6 = formatter.string(for: value6)

print(String(describing: roundedValue1)) // prints Optional("-0")
print(String(describing: roundedValue2)) // prints Optional("-0")
print(String(describing: roundedValue3)) // prints Optional("-1")
print(String(describing: roundedValue4)) // prints Optional("1")
print(String(describing: roundedValue5)) // prints Optional("1")
print(String(describing: roundedValue6)) // prints Optional("1")
于 2017-03-22T13:56:44.747 回答
23

在 swift 5 上使用它

let x = 6.5

// Equivalent to the C 'round' function:
print(x.rounded(.toNearestOrAwayFromZero))
// Prints "7.0"

// Equivalent to the C 'trunc' function:
print(x.rounded(.towardZero))
// Prints "6.0"

// Equivalent to the C 'ceil' function:
print(x.rounded(.up))
// Prints "7.0"

// Equivalent to the C 'floor' function:
print(x.rounded(.down))
// Prints "6.0"
于 2019-07-08T12:02:25.183 回答
21

最正确的语法可能是:

var f: CGFloat = 2.5
var roundedF = CGFloat(ceil(Double(f)))

要使用ceil,我将首先制作CGFloataDouble和天花板之后,我将其转换回CGFloat.

CGFloat定义为CFloat或时有效CDouble

您还可ceil以为浮点数定义一个(这实际上已在 Swift 2 中实现):

func ceil(f: CFloat) -> CFloat {
   return ceilf(f)
}

然后就可以直接打电话了

var roundedF: CGFloat = ceil(f)

同时保持类型安全。

我实际上认为这应该是 Apple 选择的解决方案,而不是单独的ceilceilf函数,因为它们在 Swift 中没有意义。

于 2014-06-12T12:05:13.063 回答
10

Swift 标准库中,您也可以就地对其进行舍入:

var value: CGFloat = -5.7
value.round(.up) // -5.0
于 2014-06-12T10:26:19.480 回答
5

建立在holex的答案之上。我做了

func accurateRound(value: Double) -> Int {

            var d : Double = value - Double(Int(value))

            if d < 0.5 {
                return Int(value)
            } else {
                return Int(value) + 1
            }
        }

-编辑扩展版-

我最近还把它变成了 Floats 的扩展,我想我也会分享 :)

extension Float {
    func roundToInt() -> Int{
        var value = Int(self)
        var f = self - Float(value)
        if f < 0.5{
            return value
        } else {
            return value + 1
        }
    }
}

这是它,所以你可以像

var f : Float = 3.3
f.roundToInt()
于 2014-09-17T23:11:22.093 回答