I want to convert a positive value to a negative value, for example:
let a: Int = 10
turn it to -10, my current idea is just use it to multiple -1
a * -1
I'm not sure if this is proper, any idea?
With Swift 5, according to your needs, you can use one of the two following ways in order to convert an integer into its additive inverse.
#1. Using negate() method
Int has a negate() method. negate() has the following declaration:
mutating func negate()
Replaces this value with its additive inverse.
The Playground code samples below show how to use negate() in order to mutate an integer and replace its value with its additive inverse:
var a = 10
a.negate()
print(a) // prints: -10
var a = -10
a.negate()
print(a) // prints: 10
Note that negate() is also available for all types that conform to SignedNumeric protocol.
#2. Using the unary minus operator (-)
The sign of a numeric value can be toggled using a prefixed -, known as the unary minus operator. The Playground code samples below show how to use it:
let a = 10
let b = -a
print(b) // prints: -10
let a = -10
let b = -a
print(b) // prints: 10
Just use - operator.
let negativeA = -a
Related
In Swift 3, I wonder why I'm able to use the half-open range operator ..< in Data.subdata(in:) but not the closed range operator ....
I've searched everywhere but can't understand why it gives me this error :
no '...' candidates produce the expected contextual result type
'Range' (aka 'Range')
Here's an example of both the one that works and the one doesn't :
import Foundation
let x = Data(bytes: [0x0, 0x1])
let y : UInt8 = x.subdata(in: 0..<2).withUnsafeBytes{$0.pointee}
let z : UInt8 = x.subdata(in: 0...1).withUnsafeBytes{$0.pointee} // This fails
Thanks!
..< is the half-open range operator, which can either create a Range or CountableRange (depending on whether the Bound is Strideable with an Integer Stride or not). The range that is created is inclusive of the lower bound, but exclusive of the upper bound.
... is the closed range operator, which can either create a ClosedRange or CountableClosedRange (same requirements as above). The range that is created is inclusive of both the upper and lower bounds.
Therefore as subdata(in:) expects a Range<Int>, you cannot use the closed range operator ... in order to construct the argument – you must use the half-open range operator instead.
However, it would be trivial to extend Data and add an overload that does accept a ClosedRange<Int>, which would allow you to use the closed range operator.
extension Data {
func subdata(in range: ClosedRange<Index>) -> Data {
return subdata(in: range.lowerBound ..< range.upperBound + 1)
}
}
let x = Data(bytes: [0x0, 0x1])
let z : UInt8 = x.subdata(in: 0...1).withUnsafeBytes {$0.pointee}
At-risk of my comment being closed I'll speak out anyway - I followed the advice of a closed/deleted comment as the selected answer did not work with Swift 5. The working solution was:
x.subdata(in: Range(0...1))
I assume this has to do with interpretations of "Range" vs "NSRange" - but honestly I don't know.
I'm new to Swift and I was trying to make something which coverts any base 10 number to a different base. I started by making a function which finds the the greatest exponent value for a base and a number. For example, if the number was 26 and the base was 5, the greatest exponent would be 2. I created the program but it always gives me an error. I feel like it might have something to do with the Double(num/exponentedBase), but I'm not sure. Finally, is there a better way to do this. Please help.
The xor operator in the first line in combination with the division in the second line of your functions is causing the exception.
The xor operator returns a new number whose bits are set to 1 where the input bits are different and are set to 0 where the input bits are the same (see https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html, chapter Bitwise XOR operator).
Therefor your variable "exponentedbase" can be 0 and it is possible that you are trying to divide through 0, which causes the exception.
When you print the values of your greatestCommonExponent function with num 12 and base 2, you get the following result:
first call:
num: 12
base: 2
exponent: 1
exponentedbase: 3
second call:
num: 12
base: 2
exponent: 2
exponentedbase: 0
You should add a guard statement to make your code save. (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ControlFlow.html#//apple_ref/doc/uid/TP40014097-CH9-ID120, chapter "early exit")
Edit:
The ^ operator in Swift is the XOR function. The statement 2^2 will compare the numbers bitwise.
10 XOR 10 = 00
For further reference follow https://en.wikipedia.org/wiki/Exclusive_or or https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AdvancedOperators.html
If you want to have a pow function, you should do something like this:
How to get the Power of some Integer in Swift language?
This should work for you:
func greatestCommonExponent(num: Int, base: Int, exponent: Int = 1) -> Int {
let exponentedbase = base^^exponent
let value = Double(num/exponentedbase)
if value > 1 {
return greatestCommonExponent(num: num, base: base, exponent: exponent+1)
}
if value == 1 {
return exponent
} else {
return exponent-1
}
}
precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence }
infix operator ^^ : PowerPrecedence
func ^^ (radix: Int, power: Int) -> Int {
return Int(pow(Double(radix), Double(power)))
}
greatestCommonExponent(num: 12, base: 2)
The result of 12 base 2 is 3
I'm trying to build a simple Swift app to calculate VAT (Value Added taxes = 20%).
func taxesFree(number: Int) -> Double {
var textfield = self.inputTextField.text.toInt()!
let VAT = 0.2
var result = textfield * VAT
return result
}
For some reason I keep getting
Binary operator * cannot be applied to operands of type Int and Double
on the line
var result = textfield * VAT
You should convert one type to the other one so both variable should be the same types:
var result: Double = Double(textfield) * VAT
It's because you're trying to multiply an Int (textfield) with a Double (VAT). Because with such an operation you could lose the precision of the double Swift doesn't allow to convert one to the other so you need to explicitly cast the Int to a Double ...
var result = Double(textfield) * VAT
The problem here is that the statement given is literally true, because Swift is strongly typed and doesn't coerce implicitly. Just had a similar case myself with "binary operator '-' cannot be applied to operands of type 'Date' and 'Int'".
If you write:
var result = 10 * 0.2
...that's fine, but if you write:
var number = 10
var result = number * 0.2
...that's not fine. This is because untyped explicit values have an appropriate type selected by the compiler, so in fact the first line is taken as being var result = Double(10) * Double(0.2). After all, as a human being you might mean 10 to be floating-point or an integer - you normally wouldn't say which and would expect that to be clear from context. It might be a bit of a pain, but the idea of strong types is that after the code is parsed it can only have one valid compiled expression.
In general you would build a new value using the constructor, so var result = Double(textfield) * VAT in your case. This is different from casting (textfield as Double) because Int is not a subclass of Double; what you are doing instead is asking for a completely new Double value to be built at runtime, losing some accuracy if the value is very high or low. This is what loosely typed languages do implicitly with pretty much all immediate values, at a small but significant time cost.
In your specific case, it wasn't valuable to have an Int in the first place (even if no fraction part is possible) so what you needed was:
func taxesFree(number: Int) -> Double {
var textfield = Double(self.inputTextField.text)!
let VAT = 0.2
var result = textfield * VAT
return result
}
In my case it was just casting to CGFloat:
self.cnsMainFaqsViewHight.constant = CGFloat(self.mainFaqs.count) * 44.0
You can convert like
var result: Double = Double(textfield)
I was misunderstanding the Closed Range Operator in Swift.
You should not wrap the range in an array: [0...10]
for i in [0...10] {
// error: binary operator '+' cannot be applied to operands of type 'CountableClosedRange<Int>' and 'Int'
let i = i + 1
}
for i in 0...10 {
// ok!
let i = i + 1
}
The range is a collection that can itself be iterated. No need to wrap it in an array, as perhaps you would have in Objective-C.
0...3 -> [0, 1, 2, 3]
[0...3] -> [[0, 1, 2, 3]]
Once you realize your object is a nested collection, rather than an array of Ints, it's easy to see why you cannot use numeric operators on the object.
This worked for me when I got the same error message in Playground:
func getMilk(howManyCartons: Int){
print("Buy \(howManyCartons) cartons of milk")
let priceToPay: Float = Float(howManyCartons) * 2.35
print("Pay $\(priceToPay)")
}
getMilk(howManyCartons: 2)
I'm trying to make a calculator of growth rate (Double) that will round the result to the nearest Integer and recalculate from there, as such:
let firstUsers = 10.0
let growth = 0.1
var users = firstUsers
var week = 0
while users < 14 {
println("week \(week) has \(users) users")
users += users * growth
week += 1
}
but I've been unable so far.
EDIT
I kinda did it like so:
var firstUsers = 10.0
let growth = 0.1
var users:Int = Int(firstUsers)
var week = 0
while users <= 14 {
println("week \(week) has \(users) users")
firstUsers += firstUsers * growth
users = Int(firstUsers)
week += 1
}
Although I don't mind that it is always rounding down, I don't like it because firstUsers had to become a variable and change throughout the program (in order to make the next calculation), which I don't want it to happen.
There is a round available in the Foundation library (it's actually in Darwin, but Foundation imports Darwin and most of the time you'll want to use Foundation instead of using Darwin directly).
import Foundation
users = round(users)
Running your code in a playground and then calling:
print(round(users))
Outputs:
15.0
round() always rounds up when the decimal place is >= .5 and down when it's < .5 (standard rounding). You can use floor() to force rounding down, and ceil() to force rounding up.
If you need to round to a specific place, then you multiply by pow(10.0, number of places), round, and then divide by pow(10, number of places):
Round to 2 decimal places:
let numberOfPlaces = 2.0
let multiplier = pow(10.0, numberOfPlaces)
let num = 10.12345
let rounded = round(num * multiplier) / multiplier
print(rounded)
Outputs:
10.12
Note: Due to the way floating point math works, rounded may not always be perfectly accurate. It's best to think of it more of an approximation of rounding. If you're doing this for display purposes, it's better to use string formatting to format the number rather than using math to round it.
To round a double to the nearest integer, just use round().
var x = 3.7
x.round() // x = 4.0
If you don't want to modify the original value, then use rounded():
let x = 3.7
let y = x.rounded() // y = 4.0. x = 3.7
As one might expect (or might not), a number like 3.5 is rounded up and a number like -3.5 is rounded down. If you need different rounding behavior than that, you can use one of the rounding rules. For example:
var x = 3.7
x.round(.towardZero) // 3.0
If you need an actual Int then just cast it to one (but only if you are certain that the Double won't be greater than Int.max):
let myInt = Int(myDouble.rounded())
Notes
This answer is completely rewritten. My old answer dealt with the C math functions like round, lround, floor, and ceil. However, now that Swift has this functionality built in, I can no longer recommend using those functions. Thanks to #dfri for pointing this out to me. Check out #dfri's excellent answer here. I also did something similar for rounding a CGFloat.
Swift 3 & 4 - making use of the rounded(_:) method as blueprinted in the FloatingPoint protocol
The FloatingPoint protocol (to which e.g. Double and Float conforms) blueprints the rounded(_:) method
func rounded(_ rule: FloatingPointRoundingRule) -> Self
Where FloatingPointRoundingRule is an enum enumerating a number of different rounding rules:
case awayFromZero
Round to the closest allowed value whose magnitude is greater than or
equal to that of the source.
case down
Round to the closest allowed value that is less than or equal to the
source.
case toNearestOrAwayFromZero
Round to the closest allowed value; if two values are equally close,
the one with greater magnitude is chosen.
case toNearestOrEven
Round to the closest allowed value; if two values are equally close,
the even one is chosen.
case towardZero
Round to the closest allowed value whose magnitude is less than or
equal to that of the source.
case up
Round to the closest allowed value that is greater than or equal to
the source.
We make use of similar examples to the ones from #Suragch's excellent answer to show these different rounding options in practice.
.awayFromZero
Round to the closest allowed value whose magnitude is greater than or equal to that of the source; no direct equivalent among the C functions, as this uses, conditionally on sign of self, ceil or floor, for positive and negative values of self, respectively.
3.000.rounded(.awayFromZero) // 3.0
3.001.rounded(.awayFromZero) // 4.0
3.999.rounded(.awayFromZero) // 4.0
(-3.000).rounded(.awayFromZero) // -3.0
(-3.001).rounded(.awayFromZero) // -4.0
(-3.999).rounded(.awayFromZero) // -4.0
.down
Equivalent to the C floor function.
3.000.rounded(.down) // 3.0
3.001.rounded(.down) // 3.0
3.999.rounded(.down) // 3.0
(-3.000).rounded(.down) // -3.0
(-3.001).rounded(.down) // -4.0
(-3.999).rounded(.down) // -4.0
.toNearestOrAwayFromZero
Equivalent to the C round function.
3.000.rounded(.toNearestOrAwayFromZero) // 3.0
3.001.rounded(.toNearestOrAwayFromZero) // 3.0
3.499.rounded(.toNearestOrAwayFromZero) // 3.0
3.500.rounded(.toNearestOrAwayFromZero) // 4.0
3.999.rounded(.toNearestOrAwayFromZero) // 4.0
(-3.000).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.001).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.499).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.500).rounded(.toNearestOrAwayFromZero) // -4.0
(-3.999).rounded(.toNearestOrAwayFromZero) // -4.0
This rounding rule can also be accessed using the zero argument rounded() method.
3.000.rounded() // 3.0
// ...
(-3.000).rounded() // -3.0
// ...
.toNearestOrEven
Round to the closest allowed value; if two values are equally close, the even one is chosen; equivalent to the C rint (/very similar to nearbyint) function.
3.499.rounded(.toNearestOrEven) // 3.0
3.500.rounded(.toNearestOrEven) // 4.0 (up to even)
3.501.rounded(.toNearestOrEven) // 4.0
4.499.rounded(.toNearestOrEven) // 4.0
4.500.rounded(.toNearestOrEven) // 4.0 (down to even)
4.501.rounded(.toNearestOrEven) // 5.0 (up to nearest)
.towardZero
Equivalent to the C trunc function.
3.000.rounded(.towardZero) // 3.0
3.001.rounded(.towardZero) // 3.0
3.999.rounded(.towardZero) // 3.0
(-3.000).rounded(.towardZero) // 3.0
(-3.001).rounded(.towardZero) // 3.0
(-3.999).rounded(.towardZero) // 3.0
If the purpose of the rounding is to prepare to work with an integer (e.g. using Int by FloatPoint initialization after rounding), we might simply make use of the fact that when initializing an Int using a Double (or Float etc), the decimal part will be truncated away.
Int(3.000) // 3
Int(3.001) // 3
Int(3.999) // 3
Int(-3.000) // -3
Int(-3.001) // -3
Int(-3.999) // -3
.up
Equivalent to the C ceil function.
3.000.rounded(.up) // 3.0
3.001.rounded(.up) // 4.0
3.999.rounded(.up) // 4.0
(-3.000).rounded(.up) // 3.0
(-3.001).rounded(.up) // 3.0
(-3.999).rounded(.up) // 3.0
Addendum: visiting the source code for FloatingPoint to verify the C functions equivalence to the different FloatingPointRoundingRule rules
If we'd like, we can take a look at the source code for FloatingPoint protocol to directly see the C function equivalents to the public FloatingPointRoundingRule rules.
From swift/stdlib/public/core/FloatingPoint.swift.gyb we see that the default implementation of the rounded(_:) method makes us of the mutating round(_:) method:
public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
var lhs = self
lhs.round(rule)
return lhs
}
From swift/stdlib/public/core/FloatingPointTypes.swift.gyb we find the default implementation of round(_:), in which the equivalence between the FloatingPointRoundingRule rules and the C rounding functions is apparent:
public mutating func round(_ rule: FloatingPointRoundingRule) {
switch rule {
case .toNearestOrAwayFromZero:
_value = Builtin.int_round_FPIEEE${bits}(_value)
case .toNearestOrEven:
_value = Builtin.int_rint_FPIEEE${bits}(_value)
case .towardZero:
_value = Builtin.int_trunc_FPIEEE${bits}(_value)
case .awayFromZero:
if sign == .minus {
_value = Builtin.int_floor_FPIEEE${bits}(_value)
}
else {
_value = Builtin.int_ceil_FPIEEE${bits}(_value)
}
case .up:
_value = Builtin.int_ceil_FPIEEE${bits}(_value)
case .down:
_value = Builtin.int_floor_FPIEEE${bits}(_value)
}
}
**In Swift**
var a = 14.123456789
var b = 14.123456789
var c = 14.123456789
var d = 14.123456789
var e = 14.123456789
var f = 14.123456789
a.rounded(.up) //15
b.rounded(.down) //14
c.rounded(.awayFromZero) //15
d.rounded(.towardZero) //14
e.rounded(.toNearestOrAwayFromZero) //14
f.rounded(.toNearestOrEven) //14
Swift 3:
If you want to round to a certain digit number e.g. 5.678434 -> 5.68 you can just combine the round() or roundf() function with a multiplication:
let value:Float = 5.678434
let roundedValue = roundf(value * 100) / 100
print(roundedValue) //5.68
You can also extend FloatingPoint in Swift 3 as follow:
extension FloatingPoint {
func rounded(to n: Int) -> Self {
let n = Self(n)
return (self / n).rounded() * n
}
}
324.0.rounded(to: 5) // 325
Swift 3
var myNum = 8.09
myNum.rounded() // result = 8 and leaves myNum unmodified
A very easy solution worked for me:
if (62 % 50 != 0) {
var number = 62 / 50 + 1 // adding 1 is doing the actual "round up"
}
number contains value 2
This is the easiest way I came across
let weightValue = 143.69
print("Rounded off weight value = \(Int(weightValue))")
Alternate method:
print("Rounded off weight value = \((String(format: "%.0f", sender.value)))")
I'm in the process of getting comfortable passing unnamed functions as arguments and I am using this to practice with, based off of the examples in the Swift Programming Guide.
So we have an array of Ints:
var numbers: Int[] = [1, 2, 3, 4, 5, 6, 7]
And I apply a transform like so: (7)
func transformNumber(number: Int) -> Int {
let result = number * 3
return result
}
numbers = numbers.map(transformNumber)
Which is equal to: (7)
numbers = numbers.map({(number: Int) -> Int in
let result = number * 3
return result;
})
Which is equal to: (8)
numbers = numbers.map({number in number * 3})
Which is equal to: (8)
numbers = numbers.map({$0 * 3})
Which is equal to: (8)
numbers = numbers.map() {$0 * 3}
As you can see in the following graphic, the iteration count in the playground sidebar shows that in the furthest abstraction of a function declaration, it has an 8 count.
Question
Why is it showing as 8 iterations for the last two examples?
It's not showing 8 iterations, really. It's showing that 8 things executed on that line. There were 7 executions as part of the map function, and an 8th to do the assignment back into the numbers variable.
It looks like this could probably provide more helpful diagnostics. I would highly encourage you to provide feedback via https://bugreport.apple.com.
Slightly rewriting your experiment to use only closures, the call counts still differ by one:
Case 1: Explicitly specifying argument types (visit count is 7)
var f1 = {(number: Int) -> Int in
let result = number * 3
return result
}
numbers.map(f1)
Case 2: Implicit argument types (visit count is 8)
var f2 = {$0 * 3}
numbers.map(f2)
If the (x times) count reported by the REPL does indeed represent a count of visits to that code location, and noting that the count is greater by one in cases where the closure type arguments are not explicitly specified (e.g. f2), my guess is that at least in the playground REPL, the extra visit is to establish actual parameter types and fill that gap in the underlying AST.