Round a digit upto two decimal place in Swift - ios

I'm getting a value of digits which i'm trying to convert to two decimal places. But when i convert it it makes the result to 0.00 . The digits are this 0.24612035420731018 . When get its .2f value it shows 0.00. The code that i tried is this,
let digit = FindResturantSerivce.instance.FindResModelInstance[indexPath.row].distance
let text = String(format: "%.2f", arguments: [digit])
print(text)

If you want to really round the number, and not just format it as rounded for display purposes, then I prefer something a little more general-purpose:
extension Double {
func rounded(digits: Int) -> Double {
let multiplier = pow(10.0, Double(digits))
return (self * multiplier).rounded() / multiplier
}
}
So you can then do something like:
let foo = 3.14159.rounded(digits: 3) // 3.142

Use a format string to round up to two decimal places and convert the double to a String:
let currentRatio = Double (rxCurrentTextField.text!)! / Double (txCurrentTextField.text!)!
railRatioLabelField.text! = String(format: "%.2f", currentRatio)
Example:
let myDouble = 3.141
let doubleStr = Double(String(format: "%.2f", myDouble)) // 3.14
let myDouble = 3.141
let doubleStr = String(format: "%.2f", myDouble) // "3.14"
If you want to round up your last decimal place, you could do something like this :
let myDouble = 3.141
let doubleStr = Double(String(format: "%.2f", ceil(myDouble*100)/100)) // 3.15
let myDouble = 3.141
let doubleStr = String(format: "%.2f", ceil(myDouble*100)/100) // "3.15"

Related

Convert currency formatter to double swift

For some reason, I can't convert the Price string to double.
When I do it always returns nil.
func calculateAirfare(checkedBags: Int, distance: Int, travelers: Int) {
let bagsPrices = Double(checkedBags * 25)
let mileCosts = Double(distance) * 0.10
let price = (bagsPrices + mileCosts) * Double(travelers)
/// Format price
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
let priceString = currencyFormatter.string(from: NSNumber(value: price))
print(priceString) -> "Optional("$750.00")"
if let double = Double(priceString) {
print(double) -> nil
}
}
You can use your same formatter to go back to a number like so:
let number = currencyFormatter.number(from: priceString)
and get the doubleValue like:
let numberDouble = number.doubleValue
The price is already double from the line
let price = (bagsPrices + mileCosts) * Double(travelers)
thus no need to convert it to double.
The code below will return a string with a $ symbol
currencyFormatter.string(from: NSNumber(value: price))
To get a double from that string then you need to remove the $ symbol
which you can do using removeFirst()
priceString?.removeFirst()
After that, the string can be converted to Double.
The complete code is:
func calculateAirfare(checkedBags: Int, distance: Int, travelers: Int) {
let bagsPrices = Double(checkedBags * 25)
let mileCosts = Double(distance) * 0.10
let price = (bagsPrices + mileCosts) * Double(travelers)
/// Format price
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
var priceString = currencyFormatter.string(for: price)
priceString?.removeFirst()
print(priceString!)
if let double = Double(priceString!) {
print(double)
}
}

calculated double return scientific notation [duplicate]

This question already has answers here:
Swift double to string
(16 answers)
Closed 5 years ago.
i'm calculating a price using two doubles, however when i output it seem to return it as scientific notation with like 1.785e-05. This is however not intended how do i make sure thats this output it with 8 decimals and not scientific notation?
CODE
let price = tickerObj.price ?? 0
let quantity = Double(self.activeTextField.text ?? "0") ?? 0
let value = quantity / price
topValueField.text = "\(value.rounded(toPlaces: 8))"
ROUND EXTENSION
extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
The number itself is correct as scientific notation. If you want to present a formatted number to the user, it should be a String. Here's working code using a NumberFormatter:
extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> String? {
let fmt = NumberFormatter()
fmt.numberStyle = .decimal
fmt.maximumFractionDigits = places
return fmt.string(from: self as NSNumber)
}
}
let price = tickerObj.price ?? 0
let quantity = Double(self.activeTextField.text ?? "0") ?? 0
let value = quantity / price
topValueField.text = "\(value.rounded(toPlaces: 8) ?? "Unknown")"

Convert Kelvin into Celsius in Swift

I'm trying to retrieve the temperature from the users current location.
I am using the API from OpenWeatherMap. The problem is, they provide the temperature in Kelvin as default, and I would like it in Celsius.
I understand that I just need to subtract 273.15 from the kelvin value....? But i'm struggling to figure out where to do that.
My code for setting my labels:
var jsonData: AnyObject?
func setLabels(weatherData: NSData) {
do {
self.jsonData = try NSJSONSerialization.JSONObjectWithData(weatherData, options: []) as! NSDictionary
} catch {
//handle error here
}
if let name = jsonData!["name"] as? String {
locationLabel.text = "using your current location, \(name)"
}
if let main = jsonData!["main"] as? NSDictionary {
if let temperature = main["temp"] as? Double {
self.tempLabel.text = String(format: "%.0f", temperature)
}
}
}
Can anyone help me get this right please, as I'm really not sure where to start, thanks.
Let me know if you need to see more of my code.
if let kelvinTemp = main["temp"] as? Double {
let celsiusTemp = kelvinTemp - 273.15
self.tempLabel.text = String(format: "%.0f", celsiusTemp)
}
or simply
self.tempLabel.text = String(format: "%.0f", temperature - 273.15)
For Swift 4.2:
Use a Measurement Formatter.
let mf = MeasurementFormatter()
This method converts one temperature type (Kelvin, Celsius, Fahrenheit) to another:
func convertTemp(temp: Double, from inputTempType: UnitTemperature, to outputTempType: UnitTemperature) -> String {
mf.numberFormatter.maximumFractionDigits = 0
mf.unitOptions = .providedUnit
let input = Measurement(value: temp, unit: inputTempType)
let output = input.converted(to: outputTempType)
return mf.string(from: output)
}
Usage:
let temperature = 291.0
let celsius = convertTemp(temp: temperature, from: .kelvin, to: .celsius) // 18°C
let fahrenheit = convertTemp(temp: temperature, from: .kelvin, to: .fahrenheit) // 64°F
To output the localized temperature format, remove the line mf.unitOptions = .providedUnit
From the code above, it seems to me the right place to do this would be right after you get the temperature
if let temperatureInKelvin = main["temp"] as? Double {
let temperatureInCelsius = temperatureInKelvin - 273.15
self.tempLabel.text = String(format: "%.0f", temperature)
}
In the future though, I would probably parse your JSON values in a separate class and store them in a model object which you can call later on.
A simpler example of the above handy function (updated for Swift 5.3) would be something like:
func convertTemperature(temp: Double, from inputTempType: UnitTemperature, to outputTempType: UnitTemperature) -> Double {
let input = Measurement(value: temp, unit: inputTempType)
let output = input.converted(to: outputTempType)
return output.value
}
Here:
self.tempLabel.text = String(format: "%.0f", temperature - 273.15)
or you can do it here (pseudo syntax as I don't know Swift that well):
if let temperature = (main["temp"] as? Double) - 273.15 {
self.tempLabel.text = String(format: "%.0f", temperature)
}

Swift - How to remove a decimal from a float if the decimal is equal to 0?

I'm displaying a distance with one decimal, and I would like to remove this decimal in case it is equal to 0 (ex: 1200.0Km), how could I do that in swift?
I'm displaying this number like this:
let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: "%.1f", distanceFloat) + "Km"
Swift 3/4:
var distanceFloat1: Float = 5.0
var distanceFloat2: Float = 5.540
var distanceFloat3: Float = 5.03
extension Float {
var clean: String {
return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
}
}
print("Value \(distanceFloat1.clean)") // 5
print("Value \(distanceFloat2.clean)") // 5.54
print("Value \(distanceFloat3.clean)") // 5.03
Swift 2 (Original answer)
let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: distanceFloat == floor(distanceFloat) ? “%.0f" : "%.1f", distanceFloat) + "Km"
Or as an extension:
extension Float {
var clean: String {
return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
}
}
Use NSNumberFormatter:
let formatter = NumberFormatter()
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2
// Avoid not getting a zero on numbers lower than 1
// Eg: .5, .67, etc...
formatter.numberStyle = .decimal
let nums = [3.0, 5.1, 7.21, 9.311, 600.0, 0.5677, 0.6988]
for num in nums {
print(formatter.string(from: num as NSNumber) ?? "n/a")
}
Returns:
3
5.1
7.21
9.31
600
0.57
0.7
extension is the powerful way to do it.
Extension:
Code for Swift 2 (not Swift 3 or newer):
extension Float {
var cleanValue: String {
return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
}
}
Usage:
var sampleValue: Float = 3.234
print(sampleValue.cleanValue)
3.234
sampleValue = 3.0
print(sampleValue.cleanValue)
3
sampleValue = 3
print(sampleValue.cleanValue)
3
Sample Playground file is here.
Update of accepted answer for swift 3:
extension Float {
var cleanValue: String {
return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
}
}
usage would just be:
let someValue: Float = 3.0
print(someValue.cleanValue) //prints 3
To format it to String, follow this pattern
let aFloat: Float = 1.123
let aString: String = String(format: "%.0f", aFloat) // "1"
let aString: String = String(format: "%.1f", aFloat) // "1.1"
let aString: String = String(format: "%.2f", aFloat) // "1.12"
let aString: String = String(format: "%.3f", aFloat) // "1.123"
To cast it to Int, follow this pattern
let aInt: Int = Int(aFloat) // "1"
When you use String(format: initializer, Swift will automatically round the final digit as needed based on the following number.
You can use an extension as already mentioned, this solution is a little shorter though:
extension Float {
var shortValue: String {
return String(format: "%g", self)
}
}
Example usage:
var sample: Float = 3.234
print(sample.shortValue)
Swift 5
for Double it's same as #Frankie's answer for float
var dec: Double = 1.0
dec.clean // 1
for the extension
extension Double {
var clean: String {
return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
}
}
Swift 5.5 makes it easy
Just use the new formatted() api with a default FloatingPointFormatStyle:
let values: [Double] = [1.0, 4.5, 100.0, 7]
for value in values {
print(value.formatted(FloatingPointFormatStyle()))
}
// prints "1, 4.5, 100, 7"
In Swift 4 try this.
extension CGFloat{
var cleanValue: String{
//return String(format: 1 == floor(self) ? "%.0f" : "%.2f", self)
return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)//
}
}
//How to use - if you enter more then two-character after (.)point, it's automatically cropping the last character and only display two characters after the point.
let strValue = "32.12"
print(\(CGFloat(strValue).cleanValue)
Formatting with maximum fraction digits, without trailing zeros
This scenario is good when a custom output precision is desired.
This solution seems roughly as fast as NumberFormatter + NSNumber solution from MirekE, but one benefit could be that we're avoiding NSObject here.
extension Double {
func string(maximumFractionDigits: Int = 2) -> String {
let s = String(format: "%.\(maximumFractionDigits)f", self)
var offset = -maximumFractionDigits - 1
for i in stride(from: 0, to: -maximumFractionDigits, by: -1) {
if s[s.index(s.endIndex, offsetBy: i - 1)] != "0" {
offset = i
break
}
}
return String(s[..<s.index(s.endIndex, offsetBy: offset)])
}
}
(works also with extension Float, but not the macOS-only type Float80)
Usage: myNumericValue.string(maximumFractionDigits: 2) or myNumericValue.string()
Output for maximumFractionDigits: 2:
1.0 → "1"
0.12 → "0.12"
0.012 → "0.01"
0.0012 → "0"
0.00012 → "0"
Simple :
Int(floor(myFloatValue))
NSNumberFormatter is your friend
let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
let numberFormatter = NSNumberFormatter()
numberFormatter.positiveFormat = "###0.##"
let distance = numberFormatter.stringFromNumber(NSNumber(float: distanceFloat))!
distanceLabel.text = distance + " Km"
Here's the full code.
let numberA: Float = 123.456
let numberB: Float = 789.000
func displayNumber(number: Float) {
if number - Float(Int(number)) == 0 {
println("\(Int(number))")
} else {
println("\(number)")
}
}
displayNumber(numberA) // console output: 123.456
displayNumber(numberB) // console output: 789
Here's the most important line in-depth.
func displayNumber(number: Float) {
Strips the float's decimal digits with Int(number).
Returns the stripped number back to float to do an operation with Float(Int(number)).
Gets the decimal-digit value with number - Float(Int(number))
Checks the decimal-digit value is empty with if number - Float(Int(number)) == 0
The contents within the if and else statements doesn't need explaining.
This might be helpful too.
extension Float {
func cleanValue() -> String {
let intValue = Int(self)
if self == 0 {return "0"}
if self / Float (intValue) == 1 { return "\(intValue)" }
return "\(self)"
}
}
Usage:
let number:Float = 45.23230000
number.cleanValue()
Maybe stringByReplacingOccurrencesOfString could help you :)
let aFloat: Float = 1.000
let aString: String = String(format: "%.1f", aFloat) // "1.0"
let wantedString: String = aString.stringByReplacingOccurrencesOfString(".0", withString: "") // "1"

Swift - Remove Trailing Zeros From Double

What is the function that removes trailing zeros from doubles?
var double = 3.0
var double2 = 3.10
println(func(double)) // 3
println(func(double2)) // 3.1
You can do it this way but it will return a string:
var double = 3.0
var double2 = 3.10
func forTrailingZero(temp: Double) -> String {
var tempVar = String(format: "%g", temp)
return tempVar
}
forTrailingZero(double) //3
forTrailingZero(double2) //3.1
In Swift 4 you can do it like that:
extension Double {
func removeZerosFromEnd() -> String {
let formatter = NumberFormatter()
let number = NSNumber(value: self)
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 16 //maximum digits in Double after dot (maximum precision)
return String(formatter.string(from: number) ?? "")
}
}
example of use: print (Double("128834.567891000").removeZerosFromEnd())
result: 128834.567891
You can also count how many decimal digits has your string:
import Foundation
extension Double {
func removeZerosFromEnd() -> String {
let formatter = NumberFormatter()
let number = NSNumber(value: self)
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = (self.components(separatedBy: ".").last)!.count
return String(formatter.string(from: number) ?? "")
}
}
Removing trailing zeros in output
This scenario is good when the default output precision is desired. We test the value for potential trailing zeros, and we use a different output format depending on it.
extension Double {
var stringWithoutZeroFraction: String {
return truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
}
}
(works also with extension Float, but not Float80)
Output:
1.0 → "1"
0.1 → "0.1"
0.01 → "0.01"
0.001 → "0.001"
0.0001 → "0.0001"
Formatting with maximum fraction digits, without trailing zeros
This scenario is good when a custom output precision is desired.
This solution seems roughly as fast as NumberFormatter + NSNumber solution from MirekE, but one benefit could be that we're avoiding NSObject here.
extension Double {
func string(maximumFractionDigits: Int = 2) -> String {
let s = String(format: "%.\(maximumFractionDigits)f", self)
for i in stride(from: 0, to: -maximumFractionDigits, by: -1) {
if s[s.index(s.endIndex, offsetBy: i - 1)] != "0" {
return String(s[..<s.index(s.endIndex, offsetBy: i)])
}
}
return String(s[..<s.index(s.endIndex, offsetBy: -maximumFractionDigits - 1)])
}
}
(works also with extension Float, but not Float80)
Output for maximumFractionDigits: 2:
1.0 → "1"
0.12 → "0.12"
0.012 → "0.01"
0.0012 → "0"
0.00012 → "0"
Note that it performs a rounding (same as MirekE solution):
0.9950000 → "0.99"
0.9950001 → "1"
In case you're looking how to remove trailing zeros from a string:
string.replacingOccurrences(of: "^([\d,]+)$|^([\d,]+)\.0*$|^([\d,]+\.[0-9]*?)0*$", with: "$1$2$3", options: .regularExpression)
This will transform strings like "0.123000000" into "0.123"
All the answers i found was good but all of them had some problems like producing decimal numbers without the 0 in the beginning ( like .123 instead of 0.123). but these two will do the job with no problem :
extension Double {
func formatNumberWithFixedFraction(maximumFraction: Int = 8) -> String {
let stringFloatNumber = String(format: "%.\(maximumFraction)f", self)
return stringFloatNumber
}
func formatNumber(maximumFraction: Int = 8) -> String {
let formatter = NumberFormatter()
let number = NSNumber(value: self)
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = maximumFraction
formatter.numberStyle = .decimal
formatter.allowsFloats = true
let formattedNumber = formatter.string(from: number).unwrap
return formattedNumber
}
}
The first one converts 71238.12 with maxFraction of 8 to: 71238.12000000
but the second one with maxFraction of 8 converts it to: 71238.12
This one works for me, returning it as a String for a text label
func ridZero(result: Double) -> String {
let value = String(format: "%g", result)
return value
}
Following results
ridZero(result: 3.0) // "3"
ridZero(result: 3.5) // "3.5"

Resources