Swift equivalent of this ActionScript line of code? - swift

I'm translating the ActionScript code from this development tutorial into swift because I'm trying to teach myself BSP. I came across a line of code I don't fully understand.
var splitH:Boolean = FlxG.random() > 0.5;
Somehow, they are casting an integer as a boolean. What would be the swift equivalent of this line? It doesn't make any sense to me. How are they casting a random value as a boolean as well? Swift doesn't allow this sort of "cross-breeding".
This is my attempt at it so far:
var splitH = Int(arc4random_uniform(2) + 1)
var splitB = false
I split the line into two values because I don't know how to make this as one line. Is this the correct approach?
This doesn't work:
var splitH:Bool = Int(arc4random_uniform(2) + 1)

You can use the ternary operator here as well.
Something along the lines of
var splitH = arc4random_uniform(100) > 50 ? true : false
or simply
var splitH = arc4random_uniform(100) > 50

N.B.: Assuming FlxG.random() is returning uniform random between 0.0 and 1.0. If it has different distribution it won't work, ofc.
If we're talking about pre-4.2 Swift your line is equivalent to:
let splitH: Bool = arc4random_uniform(2) == 1
In Swift 4.2+ you may just use something like this:
let splitH: Bool = Double.random(in: 0.0 ..< 1.0) > 0.5

Related

Can this be more Swift3-like?

What I want to do is populate an Array (sequence) by appending in the elements of another Array (availableExercises), one by one. I want to do it one by one because the sequence has to hold a given number of items. The available exercises list is in nature finite, and I want to use its elements as many times as I want, as opposed to a multiple number of the available list total.
The current code included does exactly that and works. It is possible to just paste that in a Playground to see it at work.
My question is: Is there a better Swift3 way to achieve the same result? Although the code works, I'd like to not need the variable i. Swift3 allows for structured code like closures and I'm failing to see how I could use them better. It seems to me there would be a better structure for this which is just out of reach at the moment.
Here's the code:
import UIKit
let repTime = 20 //seconds
let restTime = 10 //seconds
let woDuration = 3 //minutes
let totalWOTime = woDuration * 60
let sessionTime = repTime + restTime
let totalSessions = totalWOTime / sessionTime
let availableExercises = ["push up","deep squat","burpee","HHSA plank"]
var sequence = [String]()
var i = 0
while sequence.count < totalSessions {
if i < availableExercises.count {
sequence.append(availableExercises[i])
i += 1
}
else { i = 0 }
}
sequence
You can overcome from i using modulo of sequence.count % availableExercises.count like this way.
var sequence = [String]()
while(sequence.count < totalSessions) {
let currentIndex = sequence.count % availableExercises.count
sequence.append(availableExercises[currentIndex])
}
print(sequence)
//["push up", "deep squat", "burpee", "HHSA plank", "push up", "deep squat"]
You can condense your logic by using map(_:) and the remainder operator %:
let sequence = (0..<totalSessions).map {
availableExercises[$0 % availableExercises.count]
}
map(_:) will iterate from 0 up to (but not including) totalSessions, and for each index, the corresponding element in availableExercises will be used in the result, with the remainder operator allowing you to 'wrap around' once you reach the end of availableExercises.
This also has the advantage of preallocating the resultant array (which map(_:) will do for you), preventing it from being needlessly re-allocated upon appending.
Personally, Nirav's solution is probably the best, but I can't help offering this solution, particularly because it demonstrates (pseudo-)infinite lazy sequences in Swift:
Array(
repeatElement(availableExercises, count: .max)
.joined()
.prefix(totalSessions))
If you just want to iterate over this, you of course don't need the Array(), you can leave the whole thing lazy. Wrapping it up in Array() just forces it to evaluate immediately ("strictly") and avoids the crazy BidirectionalSlice<FlattenBidirectionalCollection<Repeated<Array<String>>>> type.

Swift Rounding up Double

I am trying to round a double up to a whole number,
var numberOfBottles = totalVolume / volumeEachBottles
for example numberOfBottles = 275.0 / 250.0
that would give me 1.1, I need it to round up to 2
Try:
var numberOfBottles = totalVolume / volumeEachBottles
numberOfBottles.rounded(.up)
or
numberOfBottles.rounded(.down)
There is a built-in global function called ceil which does exactly this:
var numberOfBottles = ceil(totalVolume/volumeEachBottles)
This returns 2, as a Double.
ceil is actually declared in math.h and documented here in the OS X man pages. It is almost certainly more efficient than any other approach.
Even if you need an Int as your final result, I would start by calculating ceil like this, and then using the Int constructor on the result of the ceil calculation.
import Foundation
var numberOfBottles = 275.0 / 250.0
var rounded = ceil(numberOfBottles)
In case you are looking for rounding it to a whole number and use it in the UI then this can be useful. Just add this as the last thing in your file or in a own file:
extension Double {
func roundToInt() -> Int{
return Int(Darwin.round(self))
}
}
And use it like this if you like to have it in a textlabel:
currentTemp.text = "\(weatherData.tempCelsius.roundToInt())"
Or print it as an Int:
print(weatherData.tempCelsius.roundToInt())

How to find max value for Double and Float in Swift

Current learning Swift, there are ways to find max and min value for different kind of Integer like Int.max and Int.min.
Is there a way to find max value for Double and Float? Moreover, which document should I refer for this kind of question? I am currently reading Apple's The Swift Programming Language.
As of Swift 3+, you should use:
CGFloat.greatestFiniteMagnitude
Double.greatestFiniteMagnitude
Float.greatestFiniteMagnitude
While there’s no Double.max, it is defined in the C float.h header, which you can access in Swift via import Darwin.
import Darwin
let fmax = FLT_MAX
let dmax = DBL_MAX
These are roughly 3.4 * 10^38 and 1.79 * 10^308 respectively.
But bear in mind it’s not so simple with floating point numbers (it’s never simple with floating point numbers). When holding numbers this large, you lose precision in a similar way to losing precision with very small numbers, so:
let d = DBL_MAX
let e = d - 1.0
let diff = d - e
diff == 0.0 // true
let maxPlusOne = DBL_MAX + 1
maxPlusOne == d // true
let inf = DBL_MAX * 2
// perhaps infinity is the “maximum”
inf == Double.infinity // true
So before you get into some calculations that might possibly brush up against these limits, you should probably read up on floating point. Here and here are probably a good start.
AV's answer is fine, but I find those macros hard to remember and a bit non-obvious, so eventually I made Double.MIN and friends work:
extension Double {
static var MIN = -DBL_MAX
static var MAX_NEG = -DBL_MIN
static var MIN_POS = DBL_MIN
static var MAX = DBL_MAX
}
Don't use lowercase min and max -- those symbols are used in Swift 3.
Just write
let mxFloat = MAXFLOAT
You will get the maximum value of a float in Swift.
Also CGFloat.infinity, Double.infinity or just .infinity can be useful in such situations.
Works with swift 5
public extension Double {
/// Max double value.
static var max: Double {
return Double(greatestFiniteMagnitude)
}
/// Min double value.
static var min: Double {
return Double(-greatestFiniteMagnitude)
}
}

How to round a Double to the nearest Int in swift?

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)))")

INFINITY in Swift Lang

According to Apple's documentation, Swift doesn't support preprocessor directives. In C/Objective-c the "INFINITY" definition is very useful for some checks.
So, How do I get a number that never is less that another?
There is already buildin infinity and also a check function. And you could also directly compare them with <.
var infinity = Double.infinity
var isInfinite = infinity.isInfinite
var someDouble = 234432.0
if someDouble < infinity {
println("Less than")
} else {
println("Small than")
}
// And the answer is Less than.
For integer values, you should use Int.max.
var highestNumber = Int.max
//if you need negative infinity
var lowestNumber = Int.min
Using NSIntegerMax instead of Int.max or -1 * NSIntegerMax instead of Int.min is equivalent, but less pretty. (Thanks #Charlesism)
Perhaps you can try finite, for example,
let x:CDouble = 0.1
finite(x) // which return a CInt
For Float values,
import UIKit
typealias Space = Float
var MaxSpaceSize = Space.infinity
var space:Space = 1100
space = space * 2