INFINITY in Swift Lang - swift

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

Related

Swift equivalent of this ActionScript line of code?

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

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

Should conditional compilation be used to cope with difference in CGFloat on different architectures?

In answering this earlier question about getting a use of ceil() on a CGFloat to compile for all architectures, I suggested a solution along these lines:
var x = CGFloat(0.5)
var result: CGFloat
#if arch(x86_64) || arch(arm64)
result = ceil(x)
#else
result = ceilf(x)
#endif
// use result
(Background info for those already confused: CGFloat is a "float" type for 32-bit architecture, "double" for 64-bit architecture (i.e. the compilation target), which is why just using either of ceil() or ceilf() on it won't always compile, depending on the target architecture. And note that you don't seem to be able to use CGFLOAT_IS_DOUBLE for conditional compilation, only the architecture flags...)
Now, that's attracted some debate in the comments about fixing things at compile time versus run time, and so forth. My answer was accepted too fast to attract what might be some good debate about this, I think.
So, my new question: is the above a safe, and sensible thing to do, if you want your iOS and OS X code to run on 32- and 64-bit devices? And if it is sane and sensible, is there still a better (at least as efficient, not as "icky") solution?
Matt,
Building on your solution, and if you use it in several places, then a little extension might make it more palatable:
extension CGFloat {
var ceil: CGFloat {
#if arch(x86_64) || arch(arm64)
return ceil(x)
#else
return ceilf(x)
#endif
}
}
The rest of the code will be cleaner:
var x = CGFloat(0.5)
x.ceil
var f : CGFloat = 0.5
var result : CGFloat
result = CGFloat(ceil(Double(f)))
Tell me what I'm missing, but that seems pretty simple to me.
Note that with current version of Swift the solution below is already implemented in the standard library and all mathematical functions are properly overloaded for Double, Float and CGFloat.
Ceil is an arithmetic operation and in the same way as any other arithmetic operation, there should be an overloaded version for both Double and Float.
var f1: Float = 1.0
var f2: Float = 2.0
var d1: Double = 1.0
var d2: Double = 2.0
var f = f1 + f2
var d = d1 + d2
This works because + is overloaded and works for both types.
Unfortunately, by pulling the math functions from the C library which doesn't support function overloading, we are left with two functions instead of one - ceil and ceilf.
I think the best solution is to overload ceil for Float types:
func ceil(f: CFloat) -> CFloat {
return ceilf(f)
}
Allowing us to do:
var f: Float = 0.5
var d: Double = 0.5
var f: Float = ceil(f)
var d: Double = ceil(d)
Once we have the same operations defined for both Float and Double, even CGFloat handling will be much simpler.
To answer the comment:
Depending on target processor architecture, CGFloat can be defined either as Float or a Double. That means we should use ceil or ceilf depending on target architecture.
var cgFloat: CGFloat = 1.5
//on 64bit it's a Double
var rounded: CGFloat = ceil(cgFloat)
//on 32bit it's a Float
var rounded: CGFloat = ceilf(cgFloat)
However, we would have to use the ugly #if.
Another option is to use clever casts
var cgFloat: CGFloat = 1.5
var rounded: CGFloat = CGFloat(ceil(Double(cgFloat))
(casting first to Double, then casting the result to CGFloat)
However, when we are working with numbers, we want math functions to be transparent.
var cgFloat1: CGFloat = 1.5
var cgFloat2: CGFloat = 2.5
// this works on both 32 and 64bit architectures!
var sum: CGFloat = cgFloat1 + cgFloat 2
If we overload ceil for Float as shown above, we are able to do
var cgFloat: CGFloat = 1.5
// this works on both 32 and 64bit architectures!
var rounded: CGFloat = ceil(cgFloat)