I want to have something to happen when (-1)^k is 1 and when its -1 -> k is generated randomly.
I tried this but it doesnt work
let test:Int32 = -1
let leftOrRight:CGFloat = pow(CGFloat(test),random(min:0,max:1))
func random(min : CGFloat, max : CGFloat) -> CGFloat{
return random() * (max - min) + min
}
leftOrRight is always NaN.
You are trying to generate a CGFloat value of -1.0 or 1.0 with equal probability. You can do that by generating a value of 0 or 1 (using arc4random_uniform(2)) and testing it before assigning the CGFloat value:
let leftOrRight: CGFloat = arc4random_uniform(2) == 0 ? 1 : -1
In Swift 4.2 (Xcode 10), you could use Bool.random() to simplify it:
let leftOrRight: CGFloat = Bool.random() ? 1 : -1
If you are using Swift 4/4.1 then this should do the trick:
let leftOrRight = 2 * (Double(arc4random_uniform(2)) - 0.5)
If you are using Swift 4.2, you could use:
let array: [CGFloat] = [-1, 1]
let leftOrRight: CGFloat = array.randomElement()
If you want leftOrRightto be a random Boolean:
let leftOrRight: Bool = Bool.random()
For more on what's coming in Swift 4.2 have a look here.
Related
I hope you guys can check. when I use 5 as x it should be showing me -0.17749282815107623 but it returns -0.2792375. I couldn't where I have been doing the mistake.
var evenNumbers = [Int]()
for i in 2...10 {
if i % 2 == 0 {
evenNumbers.append(i)
}
}
func power(val: Float, power: Int)->Float{
var c:Float = 1
for i in 1...power {
c *= val
}
return c
}
func bessel(x: Float)->Float{
var j0:Float = 0
var counter = 1
var lastDetermVal:Float = 1
for eNumber in evenNumbers {
print(lastDetermVal)
if counter == 1 {
lastDetermVal *= power(val: Float(eNumber), power: 2)
j0 += (power(val: x, power: eNumber))/lastDetermVal
counter = -1
}else if counter == -1{
lastDetermVal *= power(val: Float(eNumber), power: 2)
j0 -= (power(val: x, power: eNumber))/lastDetermVal
counter = 1
}
}
return 1-j0
}
bessel(x: 5)
Function 1:
Your mistake seems to be that you didn't have enough even numbers.
var evenNumbers = [Int]()
for i in 2...10 {
if i % 2 == 0 {
evenNumbers.append(i)
}
}
After the above is run, evenNumbers will be populated with [2,4,6,8,10]. But to evaluate 10 terms, you need even numbers up to 18 or 20, depending on whether you count 1 as a "term". Therefore, you should loop up to 18 or 20:
var evenNumbers = [Int]()
for i in 2...18 { // I think the 1 at the beginning should count as a "term"
if i % 2 == 0 {
evenNumbers.append(i)
}
}
Alternatively, you can create this array like this:
let evenNumbers = (1..<10).map { $0 * 2 }
This means "for each number between 1 (inclusive) and 10 (exclusive), multiply each by 2".
Now your solution will give you an answer of -0.1776034.
Here's my (rather slow) solution:
func productOfFirstNEvenNumbers(_ n: Int) -> Float {
if n == 0 {
return 1
}
let firstNEvenNumbers = (1...n).map { Float($0) * 2.0 }
// ".reduce(1.0, *)" means "multiply everything"
return firstNEvenNumbers.reduce(1.0, *)
}
func nthTerm(_ n: Int, x: Float) -> Float {
let numerator = pow(x, Float(n) * 2)
// yes, this does recalculate the product of even numbers every time...
let product = productOfFirstNEvenNumbers(n)
let denominator = product * product
return numerator / (denominator) * pow(-1, Float(n))
}
func bessel10Terms(x: Float) -> Float {
// for each number n in the range 0..<10, get the nth term, add them together
(0..<10).map { nthTerm($0, x: x) }.reduce(0, +)
}
print(bessel10Terms(x: 5))
You code is a bit unreadable, however, I have written a simple solution so try to compare your intermediate results:
var terms: [Float] = []
let x: Float = 5
for index in 0 ..< 10 {
guard index > 0 else {
terms.append(1)
continue
}
// calculate only the multiplier for the previous term
// - (minus) to change the sign
// x * x to multiply nominator
// (Float(index * 2) * Float(index * 2) to multiply denominator
let termFactor = -(x * x) / (Float(index * 2) * Float(index * 2))
terms.append(terms[index - 1] * termFactor)
}
print(terms)
// sum the terms
let result = terms.reduce(0, +)
print(result)
One of the errors I see is the fact that you are actually calculating only 5 terms, not 10 (you iterate 1 to 10, but only even numbers).
I am sure this is an easy question to any of you are experienced in Swift, however, I just started learning how to program and have no idea where to start. What I am trying to do is a round a number to the nearest whole value, or to the third number. This is what I mean:
12.6 //Want rounded to 13
126 //Want rounded to 130
1264 //Want rounded to 1300
I know swift has a .rounded() function, and I have managed to use it to round the nearest 10th, 100th, etc., however, I cannot round the way I would like to. Any advice would be much appreciated.
Here's one way to round any Double or Int (including negative numbers) to a given number of significant figures:
func round(_ num: Double, to places: Int) -> Double {
let p = log10(abs(num))
let f = pow(10, p.rounded() - Double(places) + 1)
let rnum = (num / f).rounded() * f
return rnum
}
func round(_ num: Int, to places: Int) -> Int {
let p = log10(abs(Double(num)))
let f = pow(10, p.rounded() - Double(places) + 1)
let rnum = (Double(num) / f).rounded() * f
return Int(rnum)
}
print(round(0.265, to: 2))
print(round(1.26, to: 2))
print(round(12.6, to: 2))
print(round(126, to: 2))
print(round(1264, to: 2))
Output:
0.27
1.3
13.0
130
1300
As stated by Sulthan you can use NumberFormatter:
let formatter = NumberFormatter()
formatter.usesSignificantDigits = true
formatter.maximumSignificantDigits = 2
formatter.minimumSignificantDigits = 2
if let result = formatter.string(from: 12.6) {
print(result) // prints 13
}
One possibility to implement a rounding algorithm. I suppose you always want the result to be integer.
func round(_ number: Float, to digits: Int) -> Float {
guard number >= 0 else {
return -round(-number, to: digits)
}
let max = pow(10, Float(digits))
var numZeros = 0
var value = number
while (value >= max) {
value /= 10
numZeros += 1
}
return round(value) * pow(10, Float(numZeros))
}
print(round(12.6, to: 2)) // 13
print(round(126, to: 2)) // 130
print(round(1264, to: 2)) // 1300
I am having the same problem as earlier with a different line of code; but this time, I wasn't able to fix it with the same approach as last time:
var Y : Int = 0
var X : Int = 0
#IBOutlet var ball : UIImageView!
ball.center = CGPointMake(ball.center.x + X, ball.center.y + Y)
This is the error I am getting:
binary operator + cannot be applied to operands of type CGfloat int
Declare them, instead, as the following:
let X : CGFloat = 0.0
let Y : CGFloat = 0.0
Replying to your comment:
The error has nothing to do with them being declared as var or let.
You could declare them as var and if you so insist on declaring them as Int, you would still need to do the following:
var X : Int = 0
var Y : Int = 0
ball.center = CGPointMake(view.center.x + CGFloat(X), view.center.y + CGFloat(Y))
The problem is that you are not having the same variable types, for example you can't add bool and string.
Change it to CGFloat instead of int:
let X : CGFloat = 0.0
let Y : CGFloat = 0.0
ball.center.x is a CGFloat and X is an Int. That's where the compiler is complaining.
Swift likes you to type cast numeric types (as if there wasn't a hierarchy in numeric domains) but you can avoid that by declaring X and Y as CGFloat instead of Int.
You could also get rid of the issue for good by defining the operator (that Swift should already have imho):
infix operator + {}
func +(left:CGFloat, right:Int) -> CGFloat
{ return left + CGFloat(right) }
func +(left:Int, right:CGFloat) -> CGFloat
{ return CGFloat(left) + right }
I am trying to generate random floats between 1 and 100, but I keep getting errors everytime. Currently I am trying:
func returnDbl ()-> Double {
var randNum = Double(Float(arc4random(101) % 5))
return randNum
}
print(returnDbl())
but to no avail, would someone point me in the right direction?
arc4random is zero-based and returns values between 0 and n-1, pass 100 as the upper bounds and add 1
arc4random_uniform is easier to use, it returns an Int32 type which has to be converted to Float.
func randomFloat() -> Float {
return Float(arc4random_uniform(100) + 1)
}
or Double
func randomDouble() -> Double {
return Double(arc4random_uniform(100) + 1)
}
or generic
func returnFloatingPoint<T : FloatingPointType>()-> T {
return T(arc4random_uniform(100) + 1)
}
let float : Float = returnFloatingPoint()
let double : Double = returnFloatingPoint()
Edit
To return a non-integral Double between 1.000000 and 99.99999 with arc4random_uniform() use
func returnDouble()-> Double {
return Double(arc4random_uniform(UInt32.max)) / 0x100000000 * 99.0 + 1.0
}
0x100000000 is UInt32.max + 1
let a = 1 + drand48() * 99
drand48 is a C function that returns a double in the range [0, 1). You can call it directly from Swift. Multiplying by 99 gives you a double in the range [0, 99). Add one to get into the range [1, 100).
As drand48 returns a double, the Swift type will be Double.
As per the comment, drand48 will by default return the same sequence of numbers upon every launch. You can avoid that by seeding it. E.g.
seed48(UnsafeMutablePointer<UInt16>([arc4random(), arc4random()]))
func returnDbl ()-> Double {
var randNum = Double(Float(arc4random() % 101))
return randNum
}
Ok thank you everybody for all of your help, the setups you showed me helped me figure out how the setup should at least look, my end result is
func returnDbl ()-> Double{
var randNum = Double(Float(arc4random_uniform(99)+1)) / Double(UINT32_MAX)
return randNum
}
print(returnDbl())
it returns floats between 1 and 100.
I'm trying to generate random values between two integers. I've tried this, which starts from 0,
let randomNumber = arc4random_uniform(10)
println(randomNumber)
But I need a value between 10 and 50.
try this
let randomNumber = arc4random_uniform(40) + 10
println(randomNumber)
in general form
let lower : UInt32 = 10
let upper : UInt32 = 50
let randomNumber = arc4random_uniform(upper - lower) + lower
println(randomNumber)
This is an option for Swift 4.2 and above using the random() method, which makes it easy!
let randomInt = Int.random(in: 10...50)
The range can be a closed (a...b) or half open (a..<b) range.
If you want a reusable function with simple parameters:
func generateRandomNumber(min: Int, max: Int) -> Int {
let randomNum = Int(arc4random_uniform(UInt32(max) - UInt32(min)) + UInt32(min))
return randomNum
}
more simple way of random number generator
func random(min: Int, max: Int) -> Int {
return Int(arc4random_uniform(UInt32(max - min + 1))) + min
}