"The Swift Programming Language" contains the following sample code:
let label = "The width is "
let width = 94
let widthLabel = label + String(width)
When I changed width implicitly to Double:
let width = 94.4
a compiler error is created for the line let widthLabel = label + String(width):
Cannot invoke '+' with an argument list of type (String, String)
While I can convert the Double var to String by calling width.description, I want to know:
Why String(Integer) works but String(Double) doesn't?
Is there any difference between calling String(var) and var.description on a numerical type (Integer, Float, Double, etc)?
The reason why you can't do that is because String doesn't have an initializer accepting a double or a float, whereas it implements initializers for all integer types (Int, Uint, Int32, etc.).
So #derdida's solution is the right way to do it.
I discourage using the description property. It is not meant to convert a double to a string, but to provide a human readable textual representation of a double. So, whereas today's representation coincides with the conversion:
let width = 94.5
println(width) // Prints "94.5"
tomorrow it can be changed to something different, such as:
ninety four point five
That's still human readable, but it's not exactly a conversion of double to string.
This rule is valid for all types (structs, classes, etc.) implementing the Printable protocol: the description property should be used to describe, not to convert.
Addendum
Besides using string interpolation, we can also use the old c-like string formatting:
let pi = 3.1415
let piString = String(format: "%0.2f", arguments:[pi])
let message = "Pi is " + String(format: "%0.2f", arguments:[pi])
println(message)
I would use this when you like to create a string value:
let width:Double = 94.4
let widthLabel = "The width is \(width)"
Related
How would I convert a string value with a exponent to a double value that I can use in a calculation
Example:
var newString = "2.9747E+03"
I want to turn that string into a number I can use in formulas.
One approach: Use a NumberFormatter object.
Those objects have a method number(from:) that let you convert a String to an NSNumber.
The existing style .scientific might meet your needs, or you might need to create a custom format string.
This code works:
var numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .scientific
if let value = numberFormatter.number(from:"2.9747E+03")
{
let dVal = Double(truncating: value)
print(dVal)
}
And outputs
2974.7
As pointed out in a now-deleted answer by Dwendel, you could also use the NSDecimalNumber initializer that takes a string, and you could then convert that to a Double.
That code would look like this:
let theNumber = "-6.11104586446241e-01"
let decimalValue = NSDecimalNumber(string: theNumber)
let double = Double(truncating:decimalValue)
print(double)
The string-based initializer for NSDecimalNumber would let you convert number strings in scientific notation with less overhead, both in terms of code and memory (supposedly creating a number-formatter is fairly costly.) A StringFormatter is more flexible, though, and you could adjust the format it uses if your number strings won't convert directly to a DecimalNumber.
I am trying to code a weather app in swift and I keep getting this
error: Value of type 'Double' has no member 'roundDouble'.
This is the line resulting in the error
WeatherRow(logo: "thermometer", name: "Max temp", value: (weather.main.tempMax.roundDouble() + "°"))
struct MainResponse: Decodable {
var temp: Double
var feels_like: Double
var temp_min: Double
var temp_max: Double
var pressure: Double
var humidity: Double
}
The syntax to round is round(var), not var.roundDouble(). (example)
Using the following function call: round(weather.main.tempMax)
Instead of converting a Double to String, use a formatter. In this case you can save yourself some work by using MeasurementFormatter, example:
let formatter = MeasurementFormatter()
formatter.numberFormatter.maximumFractionDigits = 0
let maxTemperature = 42.54
let measurement = Measurement(
value: maxTemperature,
unit: UnitTemperature.celsius
)
let formattedTemperature = formatter.string(from: measurement)
print(formattedTemperature) // 43°C
In most cases you should not round floats/doubles, they are only approximations of real number, for example a double can not exactly store 1/10 for the same reason you can not store 1/3 with a finite number of decimal points, you are going to get gaps, and just have a less accurate value. The main reason to round is for display purposes, and so you should round when turning your value into a string to display, NumberFormatter has lots of control over this, you can also us c like print formatting options like "%.3f"
just a short question. In Swift it is possible to solve the following code:
var a: String;
a = "\(3*3)";
The arithmetic operation in the string will be solved. But i can´t figure out, why this following variation doesn´t work.
var a: String;
var b: String;
b = "3*3";
a = "\(b)";
In this case the arithmetic operation in var a will not be resolved. Any ideas why and how i can this get to work. Some things would be much more easier if this would work. Thanks for your answers.
In the second case, you are interpolating a string, not an arithmetic expression. In your example, it's a string you chose at compile time, but in general it might be a string from the user, or loaded from a file or over the web. In other words, at runtime b could contain some arbitrary string. The compiler isn't available at runtime to parse an arbitrary string as arithmetic.
If you want to evaluate an arbitrary string as an arithmetic formula at runtime, you can use NSExpression. Here's a very simple example:
let expn = NSExpression(format:"3+3")
println(expn.expressionValueWithObject(nil, context: nil))
// output: 6
You can also use a third-party library like DDMathParser.
Swift 4.2
let expn = "3+3"
print(expn.expressionValue(with: nil, context: nil))
But I also have a solution thats not the most effective way but could be used in some cases if your sure it's only "y+x" and not longer string.
var yNumber: Int!
var xNumber: Int!
let expn: String? = "3+3"
// Here we take to first value in the expn String.
if let firstNumber = expo?.prefix(1), let myInt = Int(firstNumber){
// This will print (Int : 3)
print("Int : \(myInt)")
// I set the value to yNumber
yNumber = myInt
}
// Here we take the last value in the expn string
if let lastNumber = optionalString?.suffix(1), let myInt = Int(lastNumber){
// This will print (Int : 3)
print("Int : \(myInt)")
// I set the value to xNumber
xNumber = myInt
}
// Now you can take the two numbers and add
print(yNumber + xNumber)
// will print (6)
I can't recommend this but it works in some cases
This won't be solved because this is not an arithmetic operation, this is a string:
"3*3"
the same as this
"String"
Everything you put in " it's a string.
The second example lets you construct a new String value from a mix of constants, variables, literals, and expressions:
"\(3*3)"
this is possible because of string interpolation \()
You inserted a string expression which swing convert and create expected result.
You can try to use evaluatePostfixNotationString method from that class.
The whole project is about recognizing math expression from camera image and calculating it after.
I've reproduced this problem in a Swift playground but haven't solved it yet...
I'd like to print one of a range of characters in a UILabel. If I explicitly declare the character, it works:
// This works.
let value: String = "\u{f096}"
label.text = value // Displays the referenced character.
However, I want to construct the String. The code below appears to produce the same result as the line above, except that it doesn't. It just produces the String \u{f096} and not the character it references.
// This doesn't work
let n: Int = 0x95 + 1
print(String(n, radix: 16)) // Prints "96".
let value: String = "\\u{f0\(String(n, radix: 16))}"
label.text = value // Displays the String "\u{f096}".
I'm probably missing something simple. Any ideas?
How about stop using string conversion voodoo and use standard library type UnicodeScalar?
You can also create Unicode scalar values directly from their numeric representation.
let airplane = UnicodeScalar(9992)
print(airplane)
// Prints "✈︎"
UnicodeScalar.init there is actually returning optional value, so you must unwrap it.
If you need String just convert it via Character type to String.
let airplaneString: String = String(Character(airplane)) // Assuming that airplane here is unwrapped
just a short question. In Swift it is possible to solve the following code:
var a: String;
a = "\(3*3)";
The arithmetic operation in the string will be solved. But i can´t figure out, why this following variation doesn´t work.
var a: String;
var b: String;
b = "3*3";
a = "\(b)";
In this case the arithmetic operation in var a will not be resolved. Any ideas why and how i can this get to work. Some things would be much more easier if this would work. Thanks for your answers.
In the second case, you are interpolating a string, not an arithmetic expression. In your example, it's a string you chose at compile time, but in general it might be a string from the user, or loaded from a file or over the web. In other words, at runtime b could contain some arbitrary string. The compiler isn't available at runtime to parse an arbitrary string as arithmetic.
If you want to evaluate an arbitrary string as an arithmetic formula at runtime, you can use NSExpression. Here's a very simple example:
let expn = NSExpression(format:"3+3")
println(expn.expressionValueWithObject(nil, context: nil))
// output: 6
You can also use a third-party library like DDMathParser.
Swift 4.2
let expn = "3+3"
print(expn.expressionValue(with: nil, context: nil))
But I also have a solution thats not the most effective way but could be used in some cases if your sure it's only "y+x" and not longer string.
var yNumber: Int!
var xNumber: Int!
let expn: String? = "3+3"
// Here we take to first value in the expn String.
if let firstNumber = expo?.prefix(1), let myInt = Int(firstNumber){
// This will print (Int : 3)
print("Int : \(myInt)")
// I set the value to yNumber
yNumber = myInt
}
// Here we take the last value in the expn string
if let lastNumber = optionalString?.suffix(1), let myInt = Int(lastNumber){
// This will print (Int : 3)
print("Int : \(myInt)")
// I set the value to xNumber
xNumber = myInt
}
// Now you can take the two numbers and add
print(yNumber + xNumber)
// will print (6)
I can't recommend this but it works in some cases
This won't be solved because this is not an arithmetic operation, this is a string:
"3*3"
the same as this
"String"
Everything you put in " it's a string.
The second example lets you construct a new String value from a mix of constants, variables, literals, and expressions:
"\(3*3)"
this is possible because of string interpolation \()
You inserted a string expression which swing convert and create expected result.
You can try to use evaluatePostfixNotationString method from that class.
The whole project is about recognizing math expression from camera image and calculating it after.