在Swift中收集CGFloat

Osk*_*son 73 rounding cgfloat ceil swift

我怎样才能在Swift中收集CGFloat?我试过ceil(CDouble(myCGFloat))但只适用于iPad Air和iPhone 5S.

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

Mat*_*son 111

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

func ceil(x: CGFloat) -> CGFloat
Run Code Online (Sandbox Code Playgroud)

...专门应对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
Run Code Online (Sandbox Code Playgroud)

  • 到目前为止可怕,但最好的解决方案.顺便问一下,#if和if之间的区别是什么? (3认同)
  • #if用于条件编译.如果您使用了类似的if语句,仍然会编译有问题的代码,并且您仍然会收到编译时错误,即使它不会在运行时运行.这样,无法在所选体系结构上编译的代码行实际上从未实际发送以进行编译. (3认同)
  • @holex:CGFloat在编译二进制文件中是浮点数还是双精度数在*编译时*完全确定.在32位二进制文​​件(可以在32位和64位硬件上运行)中,CGFloat是一个浮点数.在64位二进制文​​件(只能在64位硬件上运行)中,CGFloat是双倍的. - A*Universal binary*包含32位和64位二进制文​​件,并在运行时选择最适合硬件*的执行文件. - 所以对于这个问题(是否调用ceil()或ceilf()),只有代码被*编译为32位或64位才有意义. (2认同)

Ima*_*tit 32

使用Swift 4.2,根据您的需要,您可以选择以下3种方法中的一种来舍入a CGFloat.


#1.使用CGFloatrounded(_:)方法

FloatingPoint协议给出了符合它的rounded(_:)方法.CGFloatrounded(_:)有以下声明:

func rounded(_ rule: FloatingPointRoundingRule) -> CGFloat
Run Code Online (Sandbox Code Playgroud)

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

下面的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
Run Code Online (Sandbox Code Playgroud)

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

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

func ceil<T>(_ x: T) -> T where T : FloatingPoint
Run Code Online (Sandbox Code Playgroud)

下面的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
Run Code Online (Sandbox Code Playgroud)

#3.运用NumberFormatter

如果要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")
Run Code Online (Sandbox Code Playgroud)


Sul*_*han 20

最正确的语法可能是:

var f: CGFloat = 2.5
var roundedF = CGFloat(ceil(Double(f)))
Run Code Online (Sandbox Code Playgroud)

要使用ceil我将首先制作CGFloata Double和后天花板,我将它转换回来CGFloat.

CGFloat定义为CFloat或时,它可以工作CDouble.

你也可以定义一个ceilfor浮动(这实际上是在Swift 2中实现的):

func ceil(f: CFloat) -> CFloat {
   return ceilf(f)
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以直接打电话了

var roundedF: CGFloat = ceil(f)
Run Code Online (Sandbox Code Playgroud)

同时保持类型安全.

我真的相信这应该是苹果公司选择的解决方案,而不必单独ceilceilf功能,因为他们不斯威夫特意义.


moh*_*sen 18

在 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"
Run Code Online (Sandbox Code Playgroud)


hol*_*lex 7

Swift标准库中,您也可以将其四舍五入:

var value: CGFloat = -5.7
value.round(.up) // -5.0
Run Code Online (Sandbox Code Playgroud)


Krt*_*tko 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
            }
        }
Run Code Online (Sandbox Code Playgroud)

- 编辑扩展版 -

我最近也把这变成了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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样就可以让你如此

var f : Float = 3.3
f.roundToInt()
Run Code Online (Sandbox Code Playgroud)