CeliaLi
CeliaLi

Reputation: 313

How to truncate CGFloat values?

since I've noticed that Float and CGFloat behave differently on 32-bit and 64-bit devices, which could lead to bugs, I try to substitute all Float values with CGFloat in my project. However I couldn't figure out a way to truncate CGfloat values to 2 digits after the decimal point.

In my project I have a function that download files returns a Float value "progress" constantly, indicating how many percent of the total files has been downloaded, which is usually something like "0.3942183693039206". In this case, I need to truncate the number to "0.39" so I can make update to the UI, and here is my function:

    func updatePropertiesForPorgress(progress:CGFloat){
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        let truncated = NSString(format: "%.2f", progress)
        let float = truncated.floatValue
        self.progressTileView.rating = CGFloat(float)
    })
}

It works perfectly fine with Float values, but if I pass progress as a CGFloat value, the truncated variable would equal to "0.00": enter image description here enter image description here

Out of curiosity, I tried to replicate the situation in playground, and did it successfully. Code as simple as:

var test:CGFloat = 0.3920394829459
let truncated = NSString(format: "%.2f", test)
let float = truncated.floatValue

would have different output depending on "test" variable being a Float or a CGFloat value. If "test" is a Float value, the result would be 0.39, which is correct, but if I change it to a CGFloat, the result would be "0.00".

Can anyone help me understand what's happening, and show me how to truncate CGFloat values correctly? I tried NSNumberFormatter but it didn't work(for now).

Thanks!

Upvotes: 2

Views: 2339

Answers (1)

rintaro
rintaro

Reputation: 51911

NSString(format:_: ...) accepts CVarArgTypes:

extension NSString {
    convenience init(format: NSString, _ args: CVarArgType...)

But, as of Swift 1.1, CGFloat itself does not conforms to CVarArgType. When it passed to NSString(format:_: ...), it is converted to NSNumber.

So NSString(format: "%.2f", test) is equivalent to NSString(format: "%.2f", test as NSNumber). As a result, %.2f would be 0.00

You should explicitly convert it to Double:

NSString(format: "%.2f", Double(test))

Note that: as of Swift 1.2, Since CGFloat conforms to CVarArgType, your code works as is.

Upvotes: 4

Related Questions