Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Thursday, February 18, 2016

Precision String Format Specifier In Swift

Precision String Format Specifier In Swift


Below is how I would have previously truncated a float to two decimal places

NSLog(@" %.02f %.02f %.02f", r, g, b);  

I checked the docs and the eBook but haven't been able to figure it out. Thanks!

Answer by David Berry for Precision String Format Specifier In Swift


You can't do it (yet) with string interpolation. Your best bet is still going to be NSString formatting:

println(NSString(format:"%.2f", sqrt(2.0)))  

Extrapolating from python, it seems like a reasonable syntax might be:

@infix func % (value:Double, format:String) -> String {      return NSString(format:format, value)  }  

Which then allows you to use them as:

M_PI % "%5.3f"                // "3.142"  

You can define similar operators for all of the numeric types, unfortunately I haven't found a way to do it with generics.

Answer by Anton Tcholakov for Precision String Format Specifier In Swift


My best solution so far, following from David's response:

import Foundation    extension Int {      func format(f: String) -> String {          return NSString(format: "%\(f)d", self)      }  }    extension Double {      func format(f: String) -> String {          return NSString(format: "%\(f)f", self)      }  }    let someInt = 4, someIntFormat = "03"  println("The integer number \(someInt) formatted with \"\(someIntFormat)\" looks like \(someInt.format(someIntFormat))")  // The integer number 4 formatted with "03" looks like 004    let someDouble = 3.14159265359, someDoubleFormat = ".3"  println("The floating point number \(someDouble) formatted with \"\(someDoubleFormat)\" looks like \(someDouble.format(someDoubleFormat))")  // The floating point number 3.14159265359 formatted with ".3" looks like 3.142  

I think this is the most Swift-like solution, tying the formatting operations directly to the data type. It may well be that there is a built-in library of formatting operations somewhere, or maybe it will be released soon. Keep in mind that the language is still in beta.

Answer by realityone for Precision String Format Specifier In Swift


a simple way is:

println(String(format: "hex string: %X", 123456))  println(String(format: "a float number: %.5f", 1.0321))  

Answer by fqdn for Precision String Format Specifier In Swift


The answers given so far that have received the most votes are relying on NSString methods and are going to require that you have imported Foundation.

Having done that, though, you still have access to NSLog.

So I think the answer to the question, if you are asking how to continue using NSLog in Swift, is simply:

import Foundation

Answer by Vincent Guerci for Precision String Format Specifier In Swift


A more elegant and generic solution is to rewrite ruby / python % operator:

// Updated for beta 5  func %(format:String, args:[CVarArgType]) -> String {      return NSString(format:format, arguments:getVaList(args))  }    "Hello %@, This is pi : %.2f" % ["World", M_PI]  

Answer by Christian Dietrich for Precision String Format Specifier In Swift


here a "pure" swift solution

 var d = 1.234567  operator infix ~> {}  @infix func ~> (left: Double, right: Int) -> String {      if right == 0 {          return "\(Int(left))"      }      var k = 1.0      for i in 1..right+1 {          k = 10.0 * k      }      let n = Double(Int(left*k)) / Double(k)      return "\(n)"  }  println("\(d~>2)")  println("\(d~>1)")  println("\(d~>0)")  

Answer by hol for Precision String Format Specifier In Swift


You can still use NSLog in Swift as in Objective-C just without the @ sign.

NSLog("%.02f %.02f %.02f", r, g, b)  

Edit: After working with Swift since a while I would like to add also this variation

    var r=1.2      var g=1.3      var b=1.4      NSLog("\(r) \(g) \(b)")  

Output:

2014-12-07 21:00:42.128 MyApp[1626:60b] 1.2 1.3 1.4  

Answer by user3778351 for Precision String Format Specifier In Swift


@infix func ^(left:Double, right: Int) -> NSNumber {      let nf = NSNumberFormatter()      nf.maximumSignificantDigits = Int(right)      return  nf.numberFromString(nf.stringFromNumber(left))  }      let r = 0.52264  let g = 0.22643  let b = 0.94837    println("this is a color: \(r^3) \(g^3) \(b^3)")    // this is a color: 0.523 0.226 0.948  

Answer by otello for Precision String Format Specifier In Swift


You can also create an operator in this way

operator infix <- {}    func <- (format: String, args:[CVarArg]) -> String {      return String(format: format, arguments: args)  }    let str = "%d %.1f" <- [1453, 1.123]  

Answer by Valentin for Precision String Format Specifier In Swift


I found String.localizedStringWithFormat to work quite well:

Example:

let value: Float = 0.33333  let unit: String = "mph"    yourUILabel.text = String.localizedStringWithFormat("%.2f %@", value, unit)  

Answer by Donn for Precision String Format Specifier In Swift


Most answers here are valid. However, in case you will format the number often, consider extending the Float class to add a method that returns a formatted string. See example code below. This one achieves the same goal by using a number formatter and extension.

extension Float {      func string(fractionDigits:Int) -> String {          let formatter = NSNumberFormatter()          formatter.minimumFractionDigits = fractionDigits          formatter.maximumFractionDigits = fractionDigits          return formatter.stringFromNumber(self) ?? "\(self)"      }  }    let myVelocity:Float = 12.32982342034    println("The velocity is \(myVelocity.string(2))")  println("The velocity is \(myVelocity.string(1))")  

The console shows:

The velocity is 12.33  The velocity is 12.3  

Answer by ChikabuZ for Precision String Format Specifier In Swift


Also with rounding:

extension Float  {      func format(f: String) -> String      {          return NSString(format: "%\(f)f", self)      }      mutating func roundTo(f: String)      {          self = NSString(format: "%\(f)f", self).floatValue      }  }    extension Double  {      func format(f: String) -> String      {          return NSString(format: "%\(f)f", self)      }      mutating func roundTo(f: String)      {          self = NSString(format: "%\(f)f", self).doubleValue      }  }    x = 0.90695652173913  x.roundTo(".2")  println(x) //0.91  

Answer by nerdist colony for Precision String Format Specifier In Swift


I don't know about two decimal places, but here's how you can print floats with zero decimal places, so I'd imagine that can be 2 place, 3, places ... (Note: you must convert CGFloat to Double to pass to String(format:) or it will see a value of zero)

func logRect(r: CGRect, _ title: String = "") {      println(String(format: "[ (%.0f, %.0f), (%.0f, %.0f) ] %@",          Double(r.origin.x), Double(r.origin.y), Double(r.size.width), Double(r.size.height), title))  }  

Answer by Stuepfnick for Precision String Format Specifier In Swift


@Christian Dietrich:

instead of:

var k = 1.0      for i in 1...right+1 {          k = 10.0 * k      }  let n = Double(Int(left*k)) / Double(k)  return "\(n)"  

it could also be:

let k = pow(10.0, Double(right))  let n = Double(Int(left*k)) / k  return "\(n)"  

[correction:] Sorry for confusion* - Of course this works with Doubles. I think, most practical (if you want digits to be rounded, not cut off) it would be something like that:

infix operator ~> {}  func ~> (left: Double, right: Int) -> Double {      if right <= 0 {          return round(left)      }      let k = pow(10.0, Double(right))      return round(left*k) / k  }  

For Float only, simply replace Double with Float, pow with powf and round with roundf.
Update: I found that it is most practical to use return type Double instead of String. It works the same for String output, i.e.:

println("Pi is roughly \(3.1415926 ~> 3)")  

prints: Pi is roughly 3.142
So you can use it the same way for Strings (you can even still write: println(d ~> 2)), but additionally you can also use it to round values directly, i.e.:

d = Double(slider.value) ~> 2  

or whatever you need ?

Answer by Steyn Viljoen for Precision String Format Specifier In Swift


Why make it so complicated? You can use this instead:

import UIKit    let PI = 3.14159265359    round( PI ) // 3.0 rounded to the nearest decimal  round( PI * 100 ) / 100 //3.14 rounded to the nearest hundredth  round( PI * 1000 ) / 1000 // 3.142 rounded to the nearest thousandth  

See it work in Playground.

PS: Solution from: http://rrike.sh/xcode/rounding-various-decimal-places-swift/

Answer by Ramkumar Chintala for Precision String Format Specifier In Swift


use below method

let output = String.localizedStringWithFormat(" %.02f %.02f %.02f", r, g, b)    println(output)  

Answer by Gunnar Forsgren - Mobimation for Precision String Format Specifier In Swift


Swift2 example: Screen width of iOS device formatting the Float removing the decimal

print(NSString(format: "Screen width = %.0f pixels", CGRectGetWidth(self.view.frame)))  

Answer by paul king for Precision String Format Specifier In Swift


A version of Vincent Guerci's ruby / python % operator, updated for Swift 2.1:

func %(format:String, args:[CVarArgType]) -> String {    return String(format:format, arguments:args)  }    "Hello %@, This is pi : %.2f" % ["World", M_PI]  

Answer by doxa for Precision String Format Specifier In Swift


This is a very fast and simple way who doesn't need complex solution.

let duration = String(format: "%.01f", 3.32323242)  // result = 3.3  

Answer by Muhammad Aamir Ali for Precision String Format Specifier In Swift


Power of extension

extension Double {      var asNumber:String {          if self >= 0 {              var formatter = NSNumberFormatter()              formatter.numberStyle = .NoStyle              formatter.percentSymbol = ""              formatter.maximumFractionDigits = 1              return "\(formatter.stringFromNumber(self)!)"          }          return ""      }  }    let velocity:Float = 12.32982342034    println("The velocity is \(velocity.toNumber)")  

Output: The velocity is 12.3

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.